# -*- coding: utf-8 -*-
import base64
from binascii import unhexlify
import codecs
from hashlib import sha256
from random import choice as random_choice, randrange
import re
import string
import struct
import time
from Components.config import config
from Screens.MessageBox import MessageBox
from Plugins.Extensions.IPTVPlayer.components.asynccall import MainSessionWrapper
from Plugins.Extensions.IPTVPlayer.components.captcha_helper import CaptchaHelper
from Plugins.Extensions.IPTVPlayer.components.iptvplayerinit import GetIPTVSleep, SetIPTVPlayerLastHostError, TranslateTXT as _
from Plugins.Extensions.IPTVPlayer.iptvdm.iptvdh import DMHelper
from Plugins.Extensions.IPTVPlayer.libs import aadecode, ph, pyaes
from Plugins.Extensions.IPTVPlayer.libs.aesgcm import python_aesgcm
from Plugins.Extensions.IPTVPlayer.libs.crypto.cipher.aes_cbc import AES_CBC
from Plugins.Extensions.IPTVPlayer.libs.dehunt import dehunt
from Plugins.Extensions.IPTVPlayer.libs.e2ijson import loads as json_loads
from Plugins.Extensions.IPTVPlayer.libs.jsunpack import get_packed_data
from Plugins.Extensions.IPTVPlayer.libs.pCommon import common
from Plugins.Extensions.IPTVPlayer.libs.recaptcha_v2 import UnCaptchaReCaptcha
from Plugins.Extensions.IPTVPlayer.libs.urlparserhelper import captchaParser, decorateUrl, getDirectM3U8Playlist, getMPDLinksWithMeta, TEAMCASTPL_decryptPlayerParams, unicode_escape, unpackJSPlayerParams, VIDUPME_decryptPlayerParams
from Plugins.Extensions.IPTVPlayer.libs.youtube_dl.utils import clean_html
from Plugins.Extensions.IPTVPlayer.p2p3.manipulateStrings import ensure_binary, ensure_str
from Plugins.Extensions.IPTVPlayer.p2p3.pVer import isPY2
from Plugins.Extensions.IPTVPlayer.p2p3.UrlLib import urllib_quote, urllib_unquote, urllib_urlencode
from Plugins.Extensions.IPTVPlayer.p2p3.UrlParse import parse_qs, urljoin, urlparse
from Plugins.Extensions.IPTVPlayer.tools.e2ijs import js_execute, js_execute_ext
from Plugins.Extensions.IPTVPlayer.tools.iptvtools import CSelOneLink, formatBytes, GetCookieDir, GetDefaultLang, GetJSScriptFile, GetPluginDir, MergeDicts, printDBG, printExc, rm
from Plugins.Extensions.IPTVPlayer.tools.iptvtypes import strwithmeta

if not isPY2():
    basestring = str
    xrange = range


def rc4(cipher_text, key):
    def compat_ord(c):
        return ord(c) if isinstance(c, str) else c

    res = ensure_binary("")
    cipher_text = base64.b64decode(cipher_text)
    key_len = len(key)
    S = list(range(256))
    j = 0
    for i in range(256):
        j = (j + S[i] + ord(key[i % key_len])) % 256
        S[i], S[j] = S[j], S[i]
    i = 0
    j = 0
    for m in range(len(cipher_text)):
        i = (i + 1) % 256
        j = (j + S[i]) % 256
        S[i], S[j] = S[j], S[i]
        k = S[(S[i] + S[j]) % 256]
        res += struct.pack("B", k ^ compat_ord(cipher_text[m]))
    return ensure_str(res)


def random_seed(length=10, data=""):
    return data + "".join(random_choice(string.ascii_letters + string.digits) for x in range(length))


def tear_decode(data_file, data_seed):
    def replacer(match):
        chars = {"0": "5", "1": "6", "2": "7", "5": "0", "6": "1", "7": "2"}
        return chars[match.group(0)]

    def str2bytes(a16):
        return [ord(i) for i in a16]

    def bytes2str(a10):
        return "".join(chr(255 & b) for b in a10)

    def digest_pad(a36):
        a41 = []
        a39 = 0
        a40 = len(a36)
        a43 = 15 - (a40 % 16)
        a41.append(a43)
        while a39 < a40:
            a41.append(a36[a39])
            a39 += 1
        a45 = a43
        while a45 > 0:
            a41.append(0)
            a45 -= 1
        return a41

    def blocks2bytes(a29):
        a34 = []
        a33 = 0
        a32 = len(a29)
        while a33 < a32:
            a34 += [255 & rshift(int(a29[a33]), 24)]
            a34 += [255 & rshift(int(a29[a33]), 16)]
            a34 += [255 & rshift(int(a29[a33]), 8)]
            a34 += [255 & a29[a33]]
            a33 += 1
        return a34

    def bytes2blocks(a22):
        a27 = []
        a28 = 0
        a26 = 0
        a25 = len(a22)
        while True:
            a27.append(((255 & a22[a26]) << 24) & 0xFFFFFFFF)
            a26 += 1
            if a26 >= a25:
                break
            a27[a28] |= (255 & a22[a26]) << 16 & 0xFFFFFFFF
            a26 += 1
            if a26 >= a25:
                break
            a27[a28] |= (255 & a22[a26]) << 8 & 0xFFFFFFFF
            a26 += 1
            if a26 >= a25:
                break
            a27[a28] |= 255 & a22[a26]
            a26 += 1
            if a26 >= a25:
                break
            a28 += 1
        return a27

    def xor_blocks(a76, a77):
        return [a76[0] ^ a77[0], a76[1] ^ a77[1]]

    def unpad(a46):
        a49 = 0
        a52 = []
        a53 = 7 & a46[a49]
        a49 += 1
        a51 = len(a46) - a53
        while a49 < a51:
            a52 += [a46[a49]]
            a49 += 1
        return a52

    def rshift(a, b):
        return (a % 0x100000000) >> b

    def tea_code(a79, a80):
        a85 = a79[0]
        a83 = a79[1]
        a87 = 0
        for a86 in range(32):
            a85 += int((((int(a83) << 4) ^ rshift(int(a83), 5)) + a83) ^ (a87 + a80[(a87 & 3)]))
            a85 = int(a85 | 0)
            a87 = int(a87) - int(1640531527)
            a83 += int((((int(a85) << 4) ^ rshift(int(a85), 5)) + a85) ^ (a87 + a80[(rshift(a87, 11) & 3)]))
            a83 = int(a83 | 0)
        return [a85, a83]

    def binarydigest(a55):
        a63 = [1633837924, 1650680933, 1667523942, 1684366951]
        a62 = [1633837924, 1650680933]
        a61 = a62
        a66 = [0, 0]
        a68 = [0, 0]
        a59 = bytes2blocks(digest_pad(str2bytes(a55)))
        a65 = 0
        a67 = len(a59)
        while a65 < a67:
            a66[0] = a59[a65]
            a65 += 1
            a66[1] = a59[a65]
            a65 += 1
            a68[0] = a59[a65]
            a65 += 1
            a68[1] = a59[a65]
            a65 += 1
            a62 = tea_code(xor_blocks(a66, a62), a63)
            a61 = tea_code(xor_blocks(a68, a61), a63)
            a64 = a62[0]
            a62[0] = a62[1]
            a62[1] = a61[0]
            a61[0] = a61[1]
            a61[1] = a64
        return [a62[0], a62[1], a61[0], a61[1]]

    def ascii2bytes(a99):
        a2b = {"A": 0, "B": 1, "C": 2, "D": 3, "E": 4, "F": 5, "G": 6, "H": 7, "I": 8, "J": 9, "K": 10, "L": 11, "M": 12, "N": 13, "O": 14, "P": 15, "Q": 16, "R": 17, "S": 18, "T": 19, "U": 20, "V": 21, "W": 22, "X": 23, "Y": 24, "Z": 25, "a": 26, "b": 27, "c": 28, "d": 29, "e": 30, "f": 31, "g": 32, "h": 33, "i": 34, "j": 35, "k": 36, "l": 37, "m": 38, "n": 39, "o": 40, "p": 41, "q": 42, "r": 43, "s": 44, "t": 45, "u": 46, "v": 47, "w": 48, "x": 49, "y": 50, "z": 51, "0": 52, "1": 53, "2": 54, "3": 55, "4": 56, "5": 57, "6": 58, "7": 59, "8": 60, "9": 61, "-": 62, "_": 63}
        a6 = -1
        a7 = len(a99)
        a9 = 0
        a8 = []
        while True:
            while True:
                a6 += 1
                if a6 >= a7:
                    return a8
                if a99[a6] in a2b.keys():
                    break
            a8.insert(a9, int(int(a2b[a99[a6]]) << 2))
            while True:
                a6 += 1
                if a6 >= a7:
                    return a8
                if a99[a6] in a2b.keys():
                    break
            a3 = a2b[a99[a6]]
            a8[a9] |= rshift(int(a3), 4)
            a9 += 1
            a3 = 15 & a3
            if (a3 == 0) and (a6 == (a7 - 1)):
                return a8
            a8.insert(a9, int(a3) << 4)
            while True:
                a6 += 1
                if a6 >= a7:
                    return a8
                if a99[a6] in a2b.keys():
                    break
            a3 = a2b[a99[a6]]
            a8[a9] |= rshift(int(a3), 2)
            a9 += 1
            a3 = 3 & a3
            if (a3 == 0) and (a6 == (a7 - 1)):
                return a8
            a8.insert(a9, int(a3) << 6)
            while True:
                a6 += 1
                if a6 >= a7:
                    return a8
                if a99[a6] in a2b.keys():
                    break
            a8[a9] |= a2b[a99[a6]]
            a9 += 1
        return a8

    def ascii2binary(a0):
        return bytes2blocks(ascii2bytes(a0))

    def tea_decode(a90, a91):
        a95 = a90[0]
        a96 = a90[1]
        a97 = int(-957401312)
        for a98 in range(32):
            a96 = int(a96) - ((((int(a95) << 4) ^ rshift(int(a95), 5)) + a95) ^ (a97 + a91[(rshift(int(a97), 11) & 3)]))
            a96 = int(a96 | 0)
            a97 = int(a97) + 1640531527
            a97 = int(a97 | 0)
            a95 = int(a95) - int((((int(a96) << 4) ^ rshift(int(a96), 5)) + a96) ^ (a97 + a91[(a97 & 3)]))
            a95 = int(a95 | 0)
        return [a95, a96]

    data_seed = re.sub("[012567]", replacer, data_seed)
    new_data_seed = binarydigest(data_seed)
    new_data_file = ascii2binary(data_file)
    a69 = 0
    a70 = len(new_data_file)
    a71 = [1633837924, 1650680933]
    a73 = [0, 0]
    a74 = []
    while a69 < a70:
        a73[0] = new_data_file[a69]
        a69 += 1
        a73[1] = new_data_file[a69]
        a69 += 1
        a72 = xor_blocks(a71, tea_decode(a73, new_data_seed))
        a74 += a72
        a71[0] = a73[0]
        a71[1] = a73[1]
    return re.sub("[012567]", replacer, bytes2str(unpad(blocks2bytes(a74))))


def girc(data, url, co=None):
    cm = common()
    hdrs = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:138.0) Gecko/20100101 Firefox/138.0", "Referer": url}
    rurl = "https://www.google.com/recaptcha/api.js"
    aurl = "https://www.google.com/recaptcha/api2"
    key = re.search(r'(?:src="{0}\?.*?render|data-sitekey)="?([^"]+)'.format(rurl), data)
    if key:
        if co is None:
            co = base64.b64encode((url[:-1] + ":443").encode()).replace(b"=", b"")
        key = key.group(1)
        rurl = "{0}?render={1}".format(rurl, key)
        sts, data = cm.getPage(rurl, hdrs)
        if not sts:
            return ""
        v = re.findall("releases/([^/]+)", data)
        v = v[0]
        rdata = {"ar": 1, "k": key, "co": co, "hl": "en", "v": v, "size": "invisible", "cb": "123456789"}
        sts, data = cm.getPage("{0}/anchor?{1}".format(aurl, urllib_urlencode(rdata)), hdrs)
        if not sts:
            return ""
        rtoken = re.search('recaptcha-token.+?="([^"]+)', data)
        pdata = {"v": v, "reason": "q", "k": key, "c": rtoken.group(1), "sa": "", "co": co}
        hdrs.update({"Referer": aurl})
        sts, data = cm.getPage("{0}/reload?k={1}".format(aurl, key), hdrs, pdata)
        if not sts:
            return ""
        gtoken = re.search('rresp","([^"]+)', data)
        if gtoken:
            return gtoken.group(1)
    return ""


def InternalCipher(data, encrypt=True):
    tmp = sha256("|".join(GetPluginDir().split("/")[-2:])).digest()
    key = tmp[:16]
    iv = tmp[16:]
    cipher = AES_CBC(key=key, keySize=16)
    if encrypt:
        return cipher.encrypt(data, iv)
    return cipher.decrypt(data, iv)


class urlparser:
    def __init__(self):
        self.cm = common()
        self.pp = pageParser()
        self.hostMap = {
            "1fichier.com": self.pp.parser1FICHIERCOM,
            "222i8x.lol": self.pp.parserFILEMOON,
            "26efp.com": self.pp.parserJWPLAYER,
            "4yftwvrdz7.sbs": self.pp.parserJWPLAYER,
            "6tnutl8knw.sbs": self.pp.parserVIDGUARDTO,
            "732eg54de642sa.sbs": self.pp.parserJWPLAYER,
            "96ar.com": self.pp.parserFILEMOON,
            # a
            "adblocktape.wiki": self.pp.parserSTREAMTAPE,
            "aiavh.com": self.pp.parserJWPLAYER,
            "aliez.me": self.pp.parserJWPLAYER,
            "all3do.com": self.pp.parserDOOD,
            "anime4low.sbs": self.pp.parserJWPLAYER,
            "ankrzkz.sbs": self.pp.parserJWPLAYER,
            "ankrznm.sbs": self.pp.parserJWPLAYER,
            "antiadtape.com": self.pp.parserSTREAMTAPE,
            "arabveturk.com": self.pp.parserJWPLAYER,
            "archive.org": self.pp.parserARCHIVEORG,
            "ashortl.ink": self.pp.parserVIDMOLYME,
            "asnwish.com": self.pp.parserJWPLAYER,
            "awish.pro": self.pp.parserJWPLAYER,
            # b
            "bbc.co.uk": self.pp.parserBBC,
            "bembed.net": self.pp.parserVIDGUARDTO,
            "bestwish.lol": self.pp.parserJWPLAYER,
            "bf0skv.org": self.pp.parserFILEMOON,
            "bgwp.cc": self.pp.parserJWPLAYER,
            "bigshare.io": self.pp.parserJWPLAYER,
            "bigwarp.art": self.pp.parserJWPLAYER,
            "bigwarp.cc": self.pp.parserJWPLAYER,
            "bigwarp.io": self.pp.parserJWPLAYER,
            "bigwarp.pro": self.pp.parserJWPLAYER,
            "bingezove.com": self.pp.parserJWPLAYER,
            "browncrossing.net": self.pp.parserONLYSTREAMTV,
            "bullstream.xyz": self.pp.parserSTREAMEMBED,
            # c
            "c1z39.com": self.pp.parserFILEMOON,
            "casacinema.cc": self.pp.parserCASACINEMACC,
            "cavanhabg.com": self.pp.parserJWPLAYER,
            "cda.pl": self.pp.parserCDA,
            "cdn1.site": self.pp.parserJWPLAYER,
            "cdn4.1vid1shar.space": self.pp.parserJWPLAYER,
            "cdnwish.com": self.pp.parserJWPLAYER,
            "chuckle-tube.com": self.pp.parserVOESX,
            "cloud.mail.ru": self.pp.parserCOUDMAILRU,
            "cloudcartel.net": self.pp.parserCLOUDCARTELNET,
            "cloudstream.us": self.pp.parserCLOUDSTREAMUS,
            "coolrea.link": self.pp.parserSPORTSONLINETO,
            "csst.online": self.pp.parserSST,
            "cybervynx.com": self.pp.parserJWPLAYER,
            # d
            "d0000d.com": self.pp.parserDOOD,
            "d000d.com": self.pp.parserDOOD,
            "d0o0d.com": self.pp.parserDOOD,
            "d-s.io": self.pp.parserDOOD,
            "daddylive.club": self.pp.parserDADDYLIVE,
            "daddylive.me": self.pp.parserDADDYLIVE,
            "dailymotion.com": self.pp.parserDAILYMOTION,
            "dancima.shop": self.pp.parserJWPLAYER,
            "dartstreams.de.cool": self.pp.parserONLYSTREAMTV,
            "davioad.com": self.pp.parserJWPLAYER,
            "dhcplay.com": self.pp.parserJWPLAYER,
            "dhmu4p2hkp.sbs": self.pp.parserVIDGUARDTO,
            "dhtpre.com": self.pp.parserJWPLAYER,
            "dingtezuni.com": self.pp.parserJWPLAYER,
            "dintezuvio.com": self.pp.parserJWPLAYER,
            "do0od.com": self.pp.parserDOOD,
            "do7go.com": self.pp.parserDOOD,
            "dood.cx": self.pp.parserDOOD,
            "dood.la": self.pp.parserDOOD,
            "dood.li": self.pp.parserDOOD,
            "dood.pm": self.pp.parserDOOD,
            "dood.re": self.pp.parserDOOD,
            "dood.sh": self.pp.parserDOOD,
            "dood.so": self.pp.parserDOOD,
            "dood.stream": self.pp.parserDOOD,
            "dood.to": self.pp.parserDOOD,
            "dood.watch": self.pp.parserDOOD,
            "dood.wf": self.pp.parserDOOD,
            "dood.work": self.pp.parserDOOD,
            "dood.ws": self.pp.parserDOOD,
            "dood.yt": self.pp.parserDOOD,
            "doods.pro": self.pp.parserDOOD,
            "doods.to": self.pp.parserVEEV,
            "doodcdn.io": self.pp.parserDOOD,
            "doodstream.co": self.pp.parserDOOD,
            "doodstream.com": self.pp.parserDOOD,
            "dooodster.com": self.pp.parserDOOD,
            "dooood.com": self.pp.parserDOOD,
            "doply.net": self.pp.parserDOOD,
            "dpstream.fyi": self.pp.parserJWPLAYER,
            "dropload.io": self.pp.parserJWPLAYER,
            "dropload.tv": self.pp.parserJWPLAYER,
            "ds2play.com": self.pp.parserDOOD,
            "ds2video.com": self.pp.parserDOOD,
            "dsvplay.com": self.pp.parserDOOD,
            "dumbalag.com": self.pp.parserJWPLAYER,
            "dwish.pro": self.pp.parserJWPLAYER,
            # e
            "eb8gfmjn71.sbs": self.pp.parserJWPLAYER,
            "ebd.cda.pl": self.pp.parserCDA,
            "edbrdl7pab.sbs": self.pp.parserJWPLAYER,
            "egtpgrvh.sbs": self.pp.parserJWPLAYER,
            "embedv.net": self.pp.parserVIDGUARDTO,
            "embedwish.com": self.pp.parserJWPLAYER,
            "emturbovid.com": self.pp.parserJWPLAYER,
            "en.embedz.net": self.pp.parserJWPLAYER,
            # f
            "f16px.com": self.pp.parserf16px,
            "f51rm.com": self.pp.parserFILEMOON,
            "facebook.com": self.pp.parserFACEBOOK,
            "fastshare.cz": self.pp.parserFASTSHARECZ,
            "fastream.to": self.pp.parserJWPLAYER,
            "fdewsdc.sbs": self.pp.parserJWPLAYER,
            "filecloud.io": self.pp.parserFILECLOUDIO,
            "filefactory.com": self.pp.parserFILEFACTORYCOM,
            "filelions.live": self.pp.parserJWPLAYER,
            "filelions.online": self.pp.parserJWPLAYER,
            "filelions.site": self.pp.parserJWPLAYER,
            "filelions.to": self.pp.parserJWPLAYER,
            "filemoon.art": self.pp.parserFILEMOON,
            "filemoon.eu": self.pp.parserFILEMOON,
            "filemoon.in": self.pp.parserFILEMOON,
            "filemoon.link": self.pp.parserFILEMOON,
            "filemoon.nl": self.pp.parserFILEMOON,
            "filemoon.sx": self.pp.parserFILEMOON,
            "filemoon.to": self.pp.parserFILEMOON,
            "filemoon.wf": self.pp.parserFILEMOON,
            "fileone.tv": self.pp.parserFILEONETV,
            "file-upload.org": self.pp.parserJWPLAYER,
            "filez.tv": self.pp.parserFILEZTV,
            "flaswish.com": self.pp.parserJWPLAYER,
            "forafile.com": self.pp.parserJWPLAYER,
            "foothubhd.live": self.pp.parserSHOWSPORTXYZ,
            "forstreams.com": self.pp.parserVIUCLIPS,
            "fsdcmo.sbs": self.pp.parserJWPLAYER,
            "fslinks.org": self.pp.parserVIDGUARDTO,
            "fsst.online": self.pp.parserSST,
            "fviplions.com": self.pp.parserONLYSTREAMTV,
            # g
            "gamovideo.com": self.pp.parserGAMOVIDEOCOM,
            "ghbrisk.com": self.pp.parserJWPLAYER,
            "go-streamer.net": self.pp.parserVIDGUARDTO,
            "goodstream.one": self.pp.parserJWPLAYER,
            "goodstream.uno": self.pp.parserJWPLAYER,
            "goofy-banana.com": self.pp.parserVOESX,
            "google.com": self.pp.parserGOOGLE,
            "govid.me": self.pp.parserGOVIDME,
            "govid.site": self.pp.parserJWPLAYER,
            "gradehgplus.com": self.pp.parserJWPLAYER,
            "gsfjzmqu.sbs": self.pp.parserVIDGUARDTO,
            "gsfqzmqu.sbs": self.pp.parserJWPLAYER,
            "guccihide.com": self.pp.parserONLYSTREAMTV,
            "guerrillaforfight.com": self.pp.parserONLYSTREAMTV,
            # h
            "harpy.tv": self.pp.parserHARPYTV,
            "haxloppd.com": self.pp.parserJWPLAYER,
            "hdbestvd.online": self.pp.parserJWPLAYER,
            "hexload.com": self.pp.parserHEXLOAD,
            "hexupload.net": self.pp.parserHEXLOAD,
            "hglink.to": self.pp.parserJWPLAYER,
            "hgplaycdn.com": self.pp.parserJWPLAYER,
            "hlsflast.com": self.pp.parserJWPLAYER,
            "hlsplayer.org": self.pp.parserHLSPLAYER,
            "hlswish.com": self.pp.parserJWPLAYER,
            # i
            "iplayerhls.com": self.pp.parserJWPLAYER,
            # j
            "javsw.me": self.pp.parserJWPLAYER,
            "jodwish.com": self.pp.parserJWPLAYER,
            "junkyvideo.com": self.pp.parserJUNKYVIDEO,
            "justupload.io": self.pp.parserJUSTUPLOAD,
            # k
            "kabab.lima-city.de": self.pp.parserKABABLIMA,
            "kinoger.be": self.pp.parserJWPLAYER,
            "kinoger.p2pplay.pro": self.pp.parserSBS,
            "kinoger.pw": self.pp.parserVIDGUARDTO,
            "kinoger.re": self.pp.parserSBS,
            "kinoger.ru": self.pp.parserVOESX,
            "krakenfiles.com": self.pp.parserKRAKENFILESCOM,
            "kravaxxa.com": self.pp.parserJWPLAYER,
            # l
            "l1afav.net": self.pp.parserFILEMOON,
            "listeamed.net": self.pp.parserVIDGUARDTO,
            "liveonscore.to": self.pp.parserLIVEONSCORETV,
            "louishide.com": self.pp.parserONLYSTREAMTV,
            "lulu.st": self.pp.parserJWPLAYER,
            "lulustream.com": self.pp.parserJWPLAYER,
            "luluvid.com": self.pp.parserJWPLAYER,
            "luluvdo.com": self.pp.parserJWPLAYER,
            "luluvdoo.com": self.pp.parserJWPLAYER,
            "lylxan.com": self.pp.parserONLYSTREAMTV,
            # m
            "md3b0j6hj.com": self.pp.parserJWPLAYER,
            "mdbekjwqa.pw": self.pp.parserJWPLAYER,
            "mdfx9dc8n.net": self.pp.parserJWPLAYER,
            "mdy48tn97.com": self.pp.parserJWPLAYER,
            "mdzsmutpcvykb.net": self.pp.parserJWPLAYER,
            "mediafire.com": self.pp.parserMEDIAFIRECOM,
            "mediasetplay.mediaset.it": self.pp.parserMEDIASET,
            "mivalyo.com": self.pp.parserJWPLAYER,
            "mixdrp.co": self.pp.parserJWPLAYER,
            "mixdrp.to": self.pp.parserJWPLAYER,
            "mixdroop.co": self.pp.parserJWPLAYER,
            "mixdrop21.net": self.pp.parserJWPLAYER,
            "mixdrop23.net": self.pp.parserJWPLAYER,
            "mixdrop.ag": self.pp.parserJWPLAYER,
            "mixdrop.bz": self.pp.parserJWPLAYER,
            "mixdrop.club": self.pp.parserJWPLAYER,
            "mixdrop.co": self.pp.parserJWPLAYER,
            "mixdrop.my": self.pp.parserJWPLAYER,
            "mixdrop.nu": self.pp.parserJWPLAYER,
            "mixdrop.ps": self.pp.parserJWPLAYER,
            "mixdrop.sb": self.pp.parserJWPLAYER,
            "mixdrop.si": self.pp.parserJWPLAYER,
            "mixdrop.sn": self.pp.parserJWPLAYER,
            "mixdrop.sx": self.pp.parserJWPLAYER,
            "mixdrop.to": self.pp.parserJWPLAYER,
            "mixdropjmk.pw": self.pp.parserJWPLAYER,
            "moflix-stream.click": self.pp.parserJWPLAYER,
            "moflix-stream.day": self.pp.parserVIDGUARDTO,
            "moflix-stream.fans": self.pp.parserJWPLAYER,
            "moflix.rpmplay.xyz": self.pp.parserSBS,
            "moflix.upns.xyz": self.pp.parserSBS,
            "movearnpre.com": self.pp.parserJWPLAYER,
            "movreel.com": self.pp.parserMOVRELLCOM,
            "mp4player.site": self.pp.parserSTREAMEMBED,
            "mp4upload.com": self.pp.parserONLYSTREAMTV,
            "mwish.pro": self.pp.parserJWPLAYER,
            "mxdrop.to": self.pp.parserJWPLAYER,
            "mysportzfy.com": self.pp.parserJWPLAYER,
            "myvidplay.com": self.pp.parserDOOD,
            # n
            "nba-streams.online": self.pp.parserSHOWSPORTXYZ,
            "nflinsider.net": self.pp.parserVIDEOHOUSE,
            "ninjastream.to": self.pp.parserNINJASTREAMTO,
            "nonlimit.pl": self.pp.parserIITV,
            "nova.upn.one": self.pp.parserSBS,
            # o
            "obeywish.com": self.pp.parserJWPLAYER,
            "odnoklassniki.ru": self.pp.parserOKRU,
            "odysee.com": self.pp.parserODYSEECOM,
            "ok.ru": self.pp.parserOKRU,
            "onet.pl": self.pp.parserONETTV,
            "onet.tv": self.pp.parserONETTV,
            "ovva.tv": self.pp.parserOVVATV,
            # p
            "partners.nettvplus.com": self.pp.parserNETTVPLUSCOM,
            "peytonepre.com": self.pp.parserONLYSTREAMTV,
            "planetfastidious.net": self.pp.parserONLYSTREAMTV,
            "player.upn.one": self.pp.parserSBS,
            "playerwish.com": self.pp.parserONLYSTREAMTV,
            "playtube.ws": self.pp.parserONLYSTREAMTV,
            "polsatsport.pl": self.pp.parserPOLSATSPORTPL,
            "poophq.com": self.pp.parserVEEV,
            "pqham.com": self.pp.parserJWPLAYER,
            "promptfile.com": self.pp.parserPROMPTFILE,
            # q
            "qfer.net": self.pp.parserQFER,
            # r
            "room905.com": self.pp.parserONLYSTREAMTV,
            "rubystm.com": self.pp.parserJWPLAYER,
            "rubyvidhub.com": self.pp.parserJWPLAYER,
            "rumble.com": self.pp.parserRUMBLECOM,
            "ryderjet.com": self.pp.parserONLYSTREAMTV,
            # s
            "s3taku.pro": self.pp.parserJWPLAYER,
            "savefiles.com": self.pp.parserJWPLAYER,
            "scloud.online": self.pp.parserSTREAMTAPE,
            "seraphinapl.com": self.pp.parserJWPLAYER,
            "sendvid.com": self.pp.parserJWPLAYER,
            "sfastwish.com": self.pp.parserJWPLAYER,
            "sharevideo.pl": self.pp.parserSHAREVIDEO,
            "shavetape.cash": self.pp.parserSTREAMTAPE,
            "shiid4u.upn.one": self.pp.parserSBS,
            "showsport.xyz": self.pp.parserSHOWSPORTXYZ,
            "slmaxed.com": self.pp.parserSTREAMLARE,
            "sltube.org": self.pp.parserSTREAMLARE,
            "slwatch.cog": self.pp.parserSTREAMLARE,
            "smoothpre.com": self.pp.parserJWPLAYER,
            "soundcloud.com": self.pp.parserSOUNDCLOUDCOM,
            "sportsonline.si": self.pp.parserSPORTSONLINETO,
            "sportsonline.to": self.pp.parserSPORTSONLINETO,
            "sprocked.com": self.pp.parserSPROCKED,
            "spruto.tv": self.pp.parserSPRUTOTV,
            "stape.fun": self.pp.parserSTREAMTAPE,
            "stbhg.click": self.pp.parserJWPLAYER,
            "strcloud.club": self.pp.parserSTREAMTAPE,
            "strcloud.link": self.pp.parserSTREAMTAPE,
            "stream.moe": self.pp.parserSTREAMMOE,
            "streamable.com": self.pp.parserSTREAMABLECOM,
            "streamadblocker.xyz": self.pp.parserSTREAMTAPE,
            "streamadblockplus.com": self.pp.parserSTREAMTAPE,
            "streamatus.tk": self.pp.parserVIUCLIPS,
            "streambolt.tv": self.pp.parserJWPLAYER,
            "streamhide.to": self.pp.parserONLYSTREAMTV,
            "streamhihi.com": self.pp.parserJWPLAYER,
            "streamhls.to": self.pp.parserJWPLAYER,
            "streamhub.gg": self.pp.parserONLYSTREAMTV,
            "streamhub.link": self.pp.parserONLYSTREAMTV,
            "streamhub.to": self.pp.parserONLYSTREAMTV,
            "streamlare.com": self.pp.parserSTREAMLARE,
            "streamnoads.com": self.pp.parserSTREAMTAPE,
            "streamo.tv": self.pp.parserIITV,
            "streamruby.com": self.pp.parserJWPLAYER,
            "streamsilk.com": self.pp.parserSTREAMSILKCOM,
            "streamta.pe": self.pp.parserSTREAMTAPE,
            "streamta.site": self.pp.parserSTREAMTAPE,
            "streamtape.cc": self.pp.parserSTREAMTAPE,
            "streamtape.com": self.pp.parserSTREAMTAPE,
            "streamtape.net": self.pp.parserSTREAMTAPE,
            "streamtape.site": self.pp.parserSTREAMTAPE,
            "streamtape.to": self.pp.parserSTREAMTAPE,
            "streamtape.xyz": self.pp.parserSTREAMTAPE,
            "streamtp3.com": self.pp.parserONLYSTREAMTV,
            "streamtp4.com": self.pp.parserONLYSTREAMTV,
            "streamup.ws": self.pp.parserSTREAMUP,
            "streamvid.net": self.pp.parserONLYSTREAMTV,
            "streamvid.su": self.pp.parserJWPLAYER,
            "streamwire.net": self.pp.parserONLYSTREAMTV,
            "streamwish.fun": self.pp.parserJWPLAYER,
            "streamwish.to": self.pp.parserJWPLAYER,
            "strmup.cc": self.pp.parserSTREAMUP,
            "strmup.to": self.pp.parserSTREAMUP,
            "strtape.cloud": self.pp.parserSTREAMTAPE,
            "strtpe.link": self.pp.parserSTREAMTAPE,
            "strwish.com": self.pp.parserONLYSTREAMTV,
            "supervideo.cc": self.pp.parserJWPLAYER,
            "supervideo.tv": self.pp.parserJWPLAYER,
            "swdyu.com": self.pp.parserJWPLAYER,
            "swhoi.com": self.pp.parserJWPLAYER,
            "swiftplayers.com": self.pp.parserJWPLAYER,
            "swishsrv.com": self.pp.parserJWPLAYER,
            # t
            "tapeadsenjoyer.com": self.pp.parserSTREAMTAPE,
            "tapeadvertisement.com": self.pp.parserSTREAMTAPE,
            "tapeblocker.com": self.pp.parserSTREAMTAPE,
            "tapewithadblock.org": self.pp.parserSTREAMTAPE,
            "tiny.cc": self.pp.parserTINYCC,
            "toclipit.com": self.pp.parserVIUCLIPS,
            "trgsfjll.sbs": self.pp.parserJWPLAYER,
            "tunestream.net": self.pp.parserONLYSTREAMTV,
            "turboviplay.com": self.pp.parserJWPLAYER,
            "tusfiles.com": self.pp.parserUSERSCLOUDCOM,
            "tusfiles.net": self.pp.parserUSERSCLOUDCOM,
            "tvp.pl": self.pp.parserTVP,
            # u
            "uefa.com": self.pp.parserUEFACOM,
            "ufckhabib.com": self.pp.parserSPORTSONLINETO,
            "ultrastream.online": self.pp.parserSBS,
            "unbiasedsenseevent.com": self.pp.parserONLYSTREAMTV,
            "up4stream.com": self.pp.parserJWPLAYER,
            "upclips.online": self.pp.parserVIUCLIPS,
            "updown.icu": self.pp.parserJWPLAYER,
            "ups2up.fun": self.pp.parserJWPLAYER,
            "upstream.to": self.pp.parserONLYSTREAMTV,
            "upvideo.cc": self.pp.parserONLYSTREAMTV,
            "upzone.cc": self.pp.parserUPZONECC,
            "uqload.com": self.pp.parserJWPLAYER,
            "uqload.cx": self.pp.parserJWPLAYER,
            "uqload.io": self.pp.parserJWPLAYER,
            "uqload.ws": self.pp.parserJWPLAYER,
            "uqloads.xyz": self.pp.parserJWPLAYER,
            "userscloud.com": self.pp.parserUSERSCLOUDCOM,
            "ustreamix.com": self.pp.parserUSTREAMIXCOM,
            # v
            "v.turkvearab.com": self.pp.parserJWPLAYER,
            "v6embed.xyz": self.pp.parserVIDGUARDTO,
            "vbn2.vdbtm.shop": self.pp.parserJWPLAYER,
            "veev.to": self.pp.parserVEEV,
            "vembed.net": self.pp.parserVIDGUARDTO,
            "veuclips.com": self.pp.parserVEUCLIPS,
            "veuclipstoday.tk": self.pp.parserVIUCLIPS,
            "vevo.com": self.pp.parserVEVO,
            "vgembed.com": self.pp.parserVIDGUARDTO,
            "vgfplay.com": self.pp.parserVIDGUARDTO,
            "vgfplay.xyz": self.pp.parserVIDGUARDTO,
            "vid-guard.com": self.pp.parserVIDGUARDTO,
            "vidcloud.co": self.pp.parserVIDCLOUDCO,
            "vidcloud9.com": self.pp.parserVIDCLOUD9,
            "vide0.net": self.pp.parserDOOD,
            "vidply.com": self.pp.parserDOOD,
            "videa.hu": self.pp.parserVIDEA,
            "videakid.hu": self.pp.parserVIDEA,
            "videohouse.me": self.pp.parserVIDEOHOUSE,
            "vidora.stream": self.pp.parserJWPLAYER,
            "videostreamlet.net": self.pp.parserVIDEOSTREAMLETNET,
            "videzz.net": self.pp.parserJWPLAYER,
            "vidguard.to": self.pp.parserVIDGUARDTO,
            "vidhidefast.com": self.pp.parserJWPLAYER,
            "vidhidefun.com": self.pp.parserJWPLAYER,
            "vidhidehub.com": self.pp.parserJWPLAYER,
            "vidhidepro.com": self.pp.parserJWPLAYER,
            "vidia.tv": self.pp.parserONLYSTREAMTV,
            "vidload.co": self.pp.parserVIDLOADCO,
            "vidmoly.me": self.pp.parserVIDMOLYME,
            "vidmoly.net": self.pp.parserVIDMOLYME,
            "vidmoly.to": self.pp.parserVIDMOLYME,
            "vidoo.tv": self.pp.parserONLYSTREAMTV,
            "vidoza.co": self.pp.parserJWPLAYER,
            "vidoza.net": self.pp.parserJWPLAYER,
            "vidoza.org": self.pp.parserJWPLAYER,
            "vidshare.space": self.pp.parserJWPLAYER,
            "vidstreamup.com": self.pp.parserVIUCLIPS,
            "viduplayer.com": self.pp.parserVIDUPLAYERCOM,
            "vidzy.org": self.pp.parserJWPLAYER,
            "vimeo.com": self.pp.parseVIMEOCOM,
            "vinovo.si": self.pp.parserVINOVO,
            "vinovo.to": self.pp.parserVINOVO,
            "viuclips.net": self.pp.parserVIUCLIPS,
            "vk.com": self.pp.parserVK,
            "vkprime.com": self.pp.parserONLYSTREAMTV,
            "vkvideo.ru": self.pp.parserVK,
            "voe.sx": self.pp.parserVOESX,
            "voodc.com": self.pp.parserVOODCCOM,
            "vsports.pt": self.pp.parserVSPORTSPT,
            "vtbe.to": self.pp.parserJWPLAYER,
            "vtube.network": self.pp.parserJWPLAYER,
            "vtube.to": self.pp.parserJWPLAYER,
            "vup.to": self.pp.parserONLYSTREAMTV,
            "vvide0.com": self.pp.parserDOOD,
            # w
            "wasuytm.store": self.pp.parserSBS,
            "watch.ezplayer.me": self.pp.parserSBS,
            "watch.gxplayer.xyz": self.pp.parserSTREAMEMBED,
            "watchadsontape.com": self.pp.parserSTREAMTAPE,
            "wavehd.com": self.pp.parserJWPLAYER,
            "weakstreams.com": self.pp.parserLIVEONSCORETV,
            "webcamera.mobi": self.pp.parserWEBCAMERAPL,
            "webcamera.pl": self.pp.parserWEBCAMERAPL,
            "wishembed.pro": self.pp.parserJWPLAYER,
            "wishfast.top": self.pp.parserONLYSTREAMTV,
            "wishonly.site": self.pp.parserJWPLAYER,
            # x
            "xage.pl": self.pp.parserXAGEPL,
            "xcoic.com": self.pp.parserFILEMOON,
            "xcv2.goveed1.space": self.pp.parserJWPLAYER,
            "xvideoshare.live": self.pp.parserONLYSTREAMTV,
            # y
            "yodbox.com": self.pp.parserONLYSTREAMTV,
            "youdbox.com": self.pp.parserONLYSTREAMTV,
            "yourupload.com": self.pp.parserJWPLAYER,
            "youtu.be": self.pp.parserYOUTUBE,
            "youtube-nocookie.com": self.pp.parserYOUTUBE,
            "youtube.com": self.pp.parserYOUTUBE,
            # z
            "zerocast.tv": self.pp.parserZEROCASTTV,
            "z1ekv717.fun": self.pp.parserJWPLAYER
        }

    @staticmethod
    def getDomain(url, onlyDomain=True):
        parsed_uri = urlparse(url)
        if onlyDomain:
            domain = "{uri.netloc}".format(uri=parsed_uri)
        else:
            domain = "{uri.scheme}://{uri.netloc}/".format(uri=parsed_uri)
        return domain

    @staticmethod
    def decorateUrl(url, metaParams={}):
        return decorateUrl(url, metaParams)

    @staticmethod
    def decorateParamsFromUrl(baseUrl, overwrite=False):
        printDBG("urlparser.decorateParamsFromUrl >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" + baseUrl)
        tmp = baseUrl.split("|")
        baseUrl = strwithmeta(tmp[0].strip(), strwithmeta(baseUrl).meta)
        KEYS_TAB = list(DMHelper.HANDLED_HTTP_HEADER_PARAMS)
        KEYS_TAB.extend(["iptv_audio_url", "iptv_proto", "Host", "Accept", "MPEGTS-Live", "PROGRAM-ID"])
        if len(tmp) == 2:
            baseParams = tmp[1].strip()
            try:
                params = parse_qs(baseParams)
                printDBG("PARAMS FROM URL [%s]" % params)
                for key in params.keys():
                    if key not in KEYS_TAB:
                        continue
                    if not overwrite and key in baseUrl.meta:
                        continue
                    try:
                        baseUrl.meta[key] = params[key][0]
                    except Exception:
                        printExc()
            except Exception:
                printExc()
        baseUrl = urlparser.decorateUrl(baseUrl)
        return baseUrl

    def preparHostForSelect(self, v, resolveLink=False):
        urltab = []
        i = 0
        if len(v) > 0:
            for url in list(v.values()) if type(v) is dict else v:
                if self.checkHostSupport(url) == 1:
                    hostName = self.getHostName(url, True)
                    i = i + 1
                    if resolveLink:
                        url = self.getVideoLink(url)
                    if isinstance(url, basestring) and url.startswith("http"):
                        urltab.append({"name": (str(i) + ". " + hostName), "url": url})
        return urltab

    def getItemTitles(self, table):
        out = []
        for i in range(len(table)):
            value = table[i]
            out.append(value[0])
        return out

    def getHostName(self, url, nameOnly=False):
        hostName = strwithmeta(url).meta.get("host_name", "")
        if not hostName:
            match = re.search("https?://(?:www.)?(.+?)/", url)
            if match:
                hostName = match.group(1)
                if nameOnly:
                    n = hostName.split(".")
                    try:
                        hostName = n[-2]
                    except Exception:
                        printExc()
            hostName = hostName.lower()
        printDBG("_________________getHostName: [%s] -> [%s]" % (url, hostName))
        return hostName

    def getParser(self, url, host=None):
        if None is host:
            host = self.getHostName(url)
        parser = self.hostMap.get(host, None)
        if None is parser:
            host2 = host[host.find(".") + 1:]
            printDBG("urlparser.getParser II try host[%s]->host2[%s]" % (host, host2))
            parser = self.hostMap.get(host2, None)
        return parser

    def checkHostSupport(self, url):
        # -1 - not supported
        #  0 - unknown
        #  1 - supported
        host = self.getHostName(url)
        # quick fix
        if host == "facebook.com" and "likebox.php" in url or "like.php" in url or "/groups/" in url:
            return 0
        ret = 0
        parser = self.getParser(url, host)
        if None is not parser:
            return 1
        elif self.isHostsNotSupported(host):
            return -1
        return ret

    def isHostsNotSupported(self, host):
        return host in ["rapidgator.net", "oboom.com"]

    def getVideoLinkExt(self, url):
        urltab = []
        try:
            ret = self.getVideoLink(url, True)
            if isinstance(ret, basestring):
                if len(ret) > 0:
                    host = self.getHostName(url)
                    urltab.append({"name": host, "url": ret})
            elif isinstance(ret, (list, tuple)):
                urltab = ret
            for idx in range(len(urltab)):
                if not self.cm.isValidUrl(url):
                    continue
                url = strwithmeta(urltab[idx]["url"])
                if "User-Agent" not in url.meta:
                    url.meta["User-Agent"] = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:144.0) Gecko/20100101 Firefox/144.0"
                    urltab[idx]["url"] = url
        except Exception:
            printExc()
        return urltab

    def getVideoLink(self, url, acceptsList=False):
        try:
            url = self.decorateParamsFromUrl(url)
            nUrl = ""
            parser = self.getParser(url)
            if None is not parser:
                nUrl = parser(url)
            else:
                host = self.getHostName(url)
                if self.isHostsNotSupported(host):
                    SetIPTVPlayerLastHostError(_('Hosting "%s" not supported.') % host)
                else:
                    SetIPTVPlayerLastHostError(_('Hosting "%s" unknown.') % host)
            if isinstance(nUrl, (list, tuple)):
                if acceptsList:
                    return nUrl
                if len(nUrl) > 0:
                    return nUrl[0]["url"]

            return nUrl
        except Exception:
            printExc()
        return False


class pageParser(CaptchaHelper):
    HTTP_HEADER = {"User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Content-type": "application/x-www-form-urlencoded"}
    FICHIER_DOWNLOAD_NUM = 0

    def __init__(self):
        self.cm = common()
        self.captcha = captchaParser()
        self.ytParser = None
        self.moonwalkParser = None
        self.vevoIE = None
        self.bbcIE = None
        self.sportStream365ServIP = None
        self.COOKIE_PATH = GetCookieDir("")
        self.jscode = {}
        self.jscode["jwplayer"] = "window=this; function stub() {}; function jwplayer() {return {setup:function(){print(JSON.stringify(arguments[0]))}, onTime:stub, onPlay:stub, onComplete:stub, onReady:stub, addButton:stub}}; window.jwplayer=jwplayer;"

    def getPageCF(self, baseUrl, addParams={}, post_data=None):
        addParams["cloudflare_params"] = {"cookie_file": addParams["cookiefile"], "User-Agent": addParams["header"]["User-Agent"]}
        sts, data = self.cm.getPageCFProtection(baseUrl, addParams, post_data)
        return sts, data

    def getYTParser(self):
        if self.ytParser is None:
            try:
                from Plugins.Extensions.IPTVPlayer.libs.youtubeparser import YouTubeParser

                self.ytParser = YouTubeParser()
            except Exception:
                printExc()
                self.ytParser = None
        return self.ytParser

    def getVevoIE(self):
        if self.vevoIE is None:
            try:
                from Plugins.Extensions.IPTVPlayer.libs.youtube_dl.extractor.vevo import VevoIE

                self.vevoIE = VevoIE()
            except Exception:
                self.vevoIE = None
                printExc()
        return self.vevoIE

    def getBBCIE(self):
        if self.bbcIE is None:
            try:
                from Plugins.Extensions.IPTVPlayer.libs.youtube_dl.extractor.bbc import BBCCoUkIE

                self.bbcIE = BBCCoUkIE()
            except Exception:
                self.bbcIE = None
                printExc()
        return self.bbcIE

    def _findLinks(self, data, serverName="", linkMarker=r"""['"]?file['"]?[ ]*:[ ]*['"](http[^"^']+)['"][,}]""", m1="sources", m2="]", contain="", meta={}):
        urltab = []

        def _isSmil(data):
            return data.split("?")[0].endswith(".smil")

        def _getSmilUrl(url):
            if _isSmil(url):
                SWF_URL = ""
                # get stream link
                sts, data = self.cm.getPage(url)
                if sts:
                    base = self.cm.ph.getSearchGroups(data, 'base="([^"]+?)"')[0]
                    src = self.cm.ph.getSearchGroups(data, 'src="([^"]+?)"')[0]
                    # if ':' in src:
                    #    src = src.split(':')[1]
                    if base.startswith("rtmp"):
                        return base + "/" + src + " swfUrl=%s pageUrl=%s" % (SWF_URL, url)
            return ""

        subTracks = []
        subData = self.cm.ph.getDataBeetwenReMarkers(data, re.compile(r"""['"]?tracks['"]?\s*?:"""), re.compile("]"), False)[1].split("}")
        for item in subData:
            kind = self.cm.ph.getSearchGroups(item, r"""['"]?kind['"]?\s*?:\s*?['"]([^"^']+?)['"]""")[0].lower()
            if kind != "captions":
                continue
            src = self.cm.ph.getSearchGroups(item, r"""['"]?file['"]?\s*?:\s*?['"](https?://[^"^']+?)['"]""")[0]
            if src == "":
                continue
            label = self.cm.ph.getSearchGroups(item, r"""label['"]?\s*?:\s*?['"]([^"^']+?)['"]""")[0]
            format = src.split("?", 1)[0].split(".")[-1].lower()
            if format not in ["srt", "vtt"]:
                continue
            if "empty" in src.lower():
                continue
            subTracks.append({"title": label, "url": src, "lang": "unk", "format": "srt"})
        srcData = self.cm.ph.getDataBeetwenMarkers(data, m1, m2, False)[1].split("},")
        for item in srcData:
            item += "},"
            if contain != "" and contain not in item:
                continue
            link = self.cm.ph.getSearchGroups(item, linkMarker)[0].replace(r"\/", "/")
            if "%3A%2F%2F" in link and "://" not in link:
                link = urllib_unquote(link)
            link = strwithmeta(link, meta)
            label = self.cm.ph.getSearchGroups(item, r"""['"]?label['"]?[ ]*:[ ]*['"]([^"^']+)['"]""")[0]
            if _isSmil(link):
                link = _getSmilUrl(link)
            if "://" in link:
                proto = "mp4"
                if link.startswith("rtmp"):
                    proto = "rtmp"
                if link.split("?")[0].endswith("m3u8"):
                    tmp = getDirectM3U8Playlist(link)
                    urltab.extend(tmp)
                else:
                    urltab.append({"name": "%s %s" % (proto + " " + serverName, label), "url": link})
                printDBG("_findLinks A")
        if len(urltab) == 0:
            printDBG("_findLinks B")
            link = self.cm.ph.getSearchGroups(data, linkMarker)[0].replace(r"\/", "/")
            link = strwithmeta(link, meta)
            if _isSmil(link):
                link = _getSmilUrl(link)
            if "://" in link:
                proto = "mp4"
                if link.startswith("rtmp"):
                    proto = "rtmp"
                urltab.append({"name": proto + " " + serverName, "url": link})
        if subTracks:
            for idx in range(len(urltab)):
                urltab[idx]["url"] = urlparser.decorateUrl(urltab[idx]["url"], {"external_sub_tracks": subTracks})
        return urltab

    def parserSPROCKED(self, url):
        url = url.replace("embed", "show")
        sts, link = self.cm.getPage(url)
        match = re.search("""url: ['"](.+?)['"],.*\nprovider""", link)
        if match:
            return match.group(1)
        return False

    def parserCDA(self, inUrl):
        printDBG("parserCDA inUrl[%r]" % inUrl)
        COOKIE_FILE = GetCookieDir("cdapl.cookie")
        self.cm.clearCookie(COOKIE_FILE, removeNames=["vToken"])
        HTTP_HEADER = {"User-Agent": "Mozilla/5.0 (PlayStation 4 4.71) AppleWebKit/601.2 (KHTML, like Gecko)"}
        defaultParams = {"header": HTTP_HEADER, "use_cookie": True, "load_cookie": True, "save_cookie": True, "cookiefile": COOKIE_FILE}

        def getPage(url, params={}, post_data=None):
            sts, data = False, None
            sts, data = self.cm.getPage(url, defaultParams, post_data)
            tries = 0
            while tries < 3:
                tries += 1
                if self.cm.meta["status_code"] == 429:
                    GetIPTVSleep().Sleep(61)
                    sts, data = self.cm.getPage(url, defaultParams, post_data)
            return sts, data

        def _decorateUrl(inUrl, referer):
            cookies = []
            cj = self.cm.getCookie(COOKIE_FILE)
            for cookie in cj:
                if (cookie.name == "vToken" and cookie.path in inUrl) or cookie.name == "PHPSESSID":
                    cookies.append("%s=%s;" % (cookie.name, cookie.value))
                    printDBG(">> \t%s \t%s \t%s \t%s" % (cookie.domain, cookie.path, cookie.name, cookie.value))
            # prepare extended link
            retUrl = strwithmeta(inUrl)
            retUrl.meta["User-Agent"] = HTTP_HEADER["User-Agent"]
            retUrl.meta["Referer"] = referer
            retUrl.meta["Cookie"] = " ".join(cookies)
            retUrl.meta["iptv_proto"] = "http"
            retUrl.meta["iptv_urlwithlimit"] = False
            retUrl.meta["iptv_livestream"] = False
            return retUrl

        vidMarker = "/video/"
        videoUrls = []
        uniqUrls = []
        tmpUrls = []
        if vidMarker not in inUrl:
            sts, data = getPage(inUrl, defaultParams)
            if sts:
                sts, match = self.cm.ph.getDataBeetwenMarkers(data, "Link do tego video:", "</a>", False)
                if sts:
                    match = self.cm.ph.getSearchGroups(match, 'href="([^"]+?)"')[0]
                else:
                    match = self.cm.ph.getSearchGroups(data, "link[ ]*?:[ ]*?'([^']+?/video/[^']+?)'")[0]
                if match.startswith("http"):
                    inUrl = match
        if vidMarker in inUrl:
            vid = self.cm.ph.getSearchGroups(inUrl + "/", "/video/([^/]+?)/")[0]
            inUrl = "https://ebd.cda.pl/620x368/" + vid
        sts, data = getPage(inUrl, defaultParams)
        if sts:
            qualities = ""
            tmp = self.cm.ph.getDataBeetwenMarkers(data, "player_data='", "'", False)[1].strip()
            if tmp == "":
                tmp = self.cm.ph.getDataBeetwenMarkers(data, 'player_data="', '"', False)[1].strip()
            try:
                tmp = clean_html(tmp).replace("&quot;", '"')
                if tmp != "":
                    data = json_loads(tmp)
                    qualities = data["video"]["qualities"]
            except Exception:
                printExc()
            printDBG("parserCDA qualities[%r]" % qualities)
            for item in qualities:
                tmpUrls.append({"name": "cda.pl " + item, "url": inUrl + "/vfilm?wersja=" + item + "&a=1&t=0"})
        if len(tmpUrls) == 0:
            tmpUrls.append({"name": "cda.pl", "url": inUrl})

        def __appendVideoUrl(params):
            if params["url"] not in uniqUrls:
                videoUrls.append(params)
                uniqUrls.append(params["url"])

        def __ca(dat):
            def rot47(s):
                x = []
                for i in range(len(s)):
                    j = ord(s[i])
                    if j >= 33 and j <= 126:
                        x.append(chr(33 + ((j + 14) % 94)))
                    else:
                        x.append(s[i])
                return "".join(x)

            def __replace(c):
                code = ord(c.group(1))
                if code <= ord("Z"):
                    tmp = 90
                else:
                    tmp = 122
                c = code + 13
                if tmp < c:
                    c -= 26
                return chr(c)

            if not self.cm.isValidUrl(dat):
                try:
                    if "uggcf" in dat:
                        dat = re.sub("([a-zA-Z])", __replace, dat)
                    else:
                        dat = rot47(urllib_unquote(dat))
                        dat = dat.replace(".cda.mp4", "").replace(".2cda.pl", ".cda.pl").replace(".3cda.pl", ".cda.pl")
                        dat = "https://" + str(dat) + ".mp4"
                    if not dat.endswith(".mp4"):
                        dat += ".mp4"
                    dat = dat.replace("0)sss", "").replace('0"d.', ".")
                except Exception:
                    dat = ""
                    printExc()
            return str(dat)

        def __jsplayer(dat):
            if self.jscode.get("data", "") == "":
                sts, self.jscode["data"] = getPage("https://ebd.cda.pl/js/player.js", defaultParams)
                if not sts:
                    return ""
            jsdata = self.jscode.get("data", "")
            jscode = self.cm.ph.getSearchGroups(jsdata, r"""var\s([a-zA-Z]+?,[a-zA-Z]+?,[a-zA-Z]+?,[a-zA-Z]+?,[a-zA-Z]+?,.*?);""")[0]
            tmp = jscode.split(",")
            jscode = ensure_str(base64.b64decode("""ZnVuY3Rpb24gbGEoYSl7fTs="""))
            jscode += self.cm.ph.getSearchGroups(jsdata, r"""(var\s[a-zA-Z]+?,[a-zA-Z]+?,[a-zA-Z]+?,[a-zA-Z]+?,[a-zA-Z]+?,.*?;)""")[0]
            for item in tmp:
                jscode += self.cm.ph.getSearchGroups(jsdata, r"(%s=function\(.*?};)" % item)[0]
            jscode += "file = '%s';" % dat
            tmp = self.cm.ph.getSearchGroups(jsdata, r"""\(this\.options,"video"\)&&\((.*?)=this\.options\.video\);""")[0] + "."
            jscode += self.cm.ph.getDataBeetwenMarkers(jsdata, "%sfile" % tmp, ";", True)[1].replace(tmp, "")
            jscode += "print(file);"
            ret = js_execute(jscode)
            if ret["sts"] and ret["code"] == 0:
                return ret["data"].strip("\n")
            return ""

        for urlItem in tmpUrls:
            if urlItem["url"].startswith("/"):
                inUrl = "https://www.cda.pl/" + urlItem["url"]
            else:
                inUrl = urlItem["url"]
            sts, pageData = getPage(inUrl, defaultParams)
            if not sts:
                continue
            tmpData = self.cm.ph.getDataBeetwenMarkers(pageData, "eval(", "</script>", False)[1]
            if tmpData != "":
                m1 = "$.get"
                if m1 in tmpData:
                    tmpData = tmpData[: tmpData.find(m1)].strip() + "</script>"
                try:
                    tmpData = unpackJSPlayerParams(tmpData, TEAMCASTPL_decryptPlayerParams, 0, True, True)
                except Exception:
                    pass
            tmpData += pageData
            tmp = self.cm.ph.getDataBeetwenMarkers(tmpData, "player_data='", "'", False)[1].strip()
            if tmp == "":
                tmp = self.cm.ph.getDataBeetwenMarkers(tmpData, 'player_data="', '"', False)[1].strip()
            tmp = clean_html(tmp).replace("&quot;", '"')
            printDBG(">>")
            printDBG(tmp)
            printDBG("<<")
            try:
                if tmp != "":
                    _tmp = json_loads(tmp)
                    tmp = __jsplayer(_tmp["video"]["file"])
                    if "cda.pl" not in tmp and _tmp["video"]["file"]:
                        tmp = __ca(_tmp["video"]["file"])
            except Exception:
                tmp = ""
                printExc()
            if tmp == "":
                data = self.cm.ph.getDataBeetwenReMarkers(tmpData, re.compile(r"""modes['"]?[\s]*:"""), re.compile("]"), False)[1]
                data = re.compile(r"""file:[\s]*['"]([^'^"]+?)['"]""").findall(data)
            else:
                data = [tmp]
            if len(data) > 0 and data[0].startswith("http"):
                __appendVideoUrl({"name": urlItem["name"] + " flv", "url": _decorateUrl(data[0], urlItem["url"])})
            if len(data) > 1 and data[1].startswith("http"):
                __appendVideoUrl({"name": urlItem["name"] + " mp4", "url": _decorateUrl(data[1], urlItem["url"])})
            if len(data) == 0:
                data = self.cm.ph.getDataBeetwenReMarkers(tmpData, re.compile(r"video:[\s]*{"), re.compile("}"), False)[1]
                data = self.cm.ph.getSearchGroups(data, r"'(http[^']+?(?:\.mp4|\.flv)[^']*?)'")[0]
                if data != "":
                    type = " flv "
                    if ".mp4" in data:
                        type = " mp4 "
                    __appendVideoUrl({"name": urlItem["name"] + type, "url": _decorateUrl(data, urlItem["url"])})
        self.jscode["data"] = ""
        return videoUrls[::-1]

    def parserDAILYMOTION(self, baseUrl):  # Partly fix 18.10
        printDBG("parserDAILYMOTION %s" % baseUrl)
        COOKIE_FILE = self.COOKIE_PATH + "dailymotion.cookie"
        HTTP_HEADER = {"User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36"}
        httpParams = {"header": HTTP_HEADER, "use_cookie": True, "save_cookie": False, "load_cookie": False, "cookiefile": COOKIE_FILE}
        video_id = re.search(r"(?:video=|/video/)([A-Za-z0-9]+)", baseUrl)
        if not video_id:
            printDBG("parserDAILYMOTION -- Video id not found")
            return []
        urlsTab = []
        sts, data = self.cm.getPage(baseUrl, httpParams)
        metadataUrl = "https://www.dailymotion.com/player/metadata/video/" + video_id.group(1)
        sts, data = self.cm.getPage(metadataUrl, httpParams)
        if sts:
            try:
                metadata = json_loads(data)
                error = metadata.get("error")
                if error:
                    title = error.get("title") or error["raw_message"]
                    printDBG("Error accessing metadata: %s " % title)
                    return []
                for quality, media_list in metadata["qualities"].items():
                    for m in media_list:
                        media_url = m.get("url")
                        media_type = m.get("type")
                        if not media_url or media_type == "application/vnd.lumberjack.manifest":
                            continue
                        media_url = urlparser.decorateUrl(media_url, {"Referer": baseUrl})
                        if media_type == "application/x-mpegURL":
                            tmpTab = getDirectM3U8Playlist(media_url, False, checkContent=True, sortWithMaxBitrate=99999999, cookieParams={"header": HTTP_HEADER, "cookiefile": COOKIE_FILE, "use_cookie": True, "save_cookie": True})
                            cookieHeader = self.cm.getCookieHeader(COOKIE_FILE)
                            for tmp in tmpTab:
                                hlsUrl = self.cm.ph.getSearchGroups(tmp["url"], r"""(https?://[^'^"]+?\.m3u8[^'^"]*?)#?""")[0]
                                redirectUrl = strwithmeta(hlsUrl, {"iptv_proto": "m3u8", "Cookie": cookieHeader, "User-Agent": HTTP_HEADER["User-Agent"]})
                                urlsTab.append({"name": "dailymotion.com: %sp hls" % (tmp.get("heigth", "0")), "url": redirectUrl, "quality": tmp.get("heigth", "0")})
                        else:
                            urlsTab.append({"name": quality, "url": media_url})
            except Exception:
                printExc
        return urlsTab

    def parserVK(self, baseUrl):  # Partly work
        printDBG("parserVK url[%s]" % baseUrl)
        COOKIE_FILE = GetCookieDir("vkcom.cookie")
        HTTP_HEADER = {"User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36"}
        params = {"header": HTTP_HEADER, "cookiefile": COOKIE_FILE, "use_cookie": True, "save_cookie": True, "load_cookie": True}

        def _doLogin(login, password):
            rm(COOKIE_FILE)
            loginUrl = "https://vk.com/login"
            sts, data = self.cm.getPage(loginUrl, params)
            if not sts:
                return False
            data = self.cm.ph.getDataBeetwenMarkers(data, '<form method="post"', "</form>", False, False)[1]
            action = self.cm.ph.getSearchGroups(data, """action=['"]([^'^"]+?)['"]""")[0]
            post_data = dict(re.findall(r'<input[^>]*name="([^"]*)"[^>]*value="([^"]*)"[^>]*>', data))
            post_data.update({"email": login, "pass": password})
            if not self.cm.isValidUrl(action):
                return False
            params["header"]["Referr"] = loginUrl
            sts, data = self.cm.getPage(action, params, post_data)
            if not sts:
                return False
            sts, data = self.cm.getPage("https://vk.com/", params)
            if not sts:
                return False
            if "logout_link" not in data:
                return False
            return True

        if baseUrl.startswith("http://"):  # NOSONAR
            baseUrl = "https" + baseUrl[4:]
        sts, data = self.cm.getPage(baseUrl, params)
        if not sts:
            return False
        login = config.plugins.iptvplayer.vkcom_login.value
        password = config.plugins.iptvplayer.vkcom_password.value
        try:
            vkcom_login = self.vkcom_login
            vkcom_pass = self.vkcom_pass
        except Exception:
            rm(COOKIE_FILE)
            vkcom_login = ""
            vkcom_pass = ""
            self.vkcom_login = ""
            self.vkcom_pass = ""
            printExc()
        if '<div id="video_ext_msg">' in data or vkcom_login != login or vkcom_pass != password:
            rm(COOKIE_FILE)
            self.vkcom_login = login
            self.vkcom_pass = password
            if login.strip() == "" or password.strip() == "":
                sessionEx = MainSessionWrapper()
                sessionEx.waitForFinishOpen(MessageBox, _("To watch videos from https://vk.com/ you need to login.\nPlease fill your login and password in the IPTVPlayer configuration."), type=MessageBox.TYPE_INFO, timeout=10)
                return False
            elif not _doLogin(login, password):
                sessionEx = MainSessionWrapper()
                sessionEx.waitForFinishOpen(MessageBox, _('Login user "%s" to https://vk.com/ failed!\nPlease check your login data in the IPTVPlayer configuration.' % login), type=MessageBox.TYPE_INFO, timeout=10)
                return False
            else:
                sts, data = self.cm.getPage(baseUrl, params)
                if not sts:
                    return False
        movieUrls = []
        item = self.cm.ph.getSearchGroups(data, r"""['"]?cache([0-9]+?)['"]?[=:]['"]?(http[^"]+?\.mp4[^;^"^']*)[;"']""", 2)
        if item[1] != "":
            cacheItem = {"name": "vk.com: " + item[0] + "p (cache)", "url": item[1].replace("\\/", "/").encode("UTF-8")}
        else:
            cacheItem = None
        tmpTab = re.findall(r"""['"]?url([0-9]+?)['"]?[=:]['"]?(http[^"]+?\.mp4[^;^"^']*)[;"']""", data)
        # prepare urls list without duplicates
        for item in tmpTab:
            item = list(item)
            if item[1].endswith("&amp"):
                item[1] = item[1][:-4]
            item[1] = item[1].replace("\\/", "/")
            found = False
            for urlItem in movieUrls:
                if item[1] == urlItem["url"]:
                    found = True
                    break
            if not found:
                movieUrls.append({"name": "vk.com: " + item[0] + "p", "url": item[1].encode("UTF-8")})
        # move default format to first position in urls list
        # default format should be a configurable
        DEFAULT_FORMAT = "vk.com: 720p"
        defaultItem = None
        for idx in range(len(movieUrls)):
            if movieUrls[idx]["name"] == DEFAULT_FORMAT:
                defaultItem = movieUrls[idx]
                del movieUrls[idx]
                break
        movieUrls = movieUrls[::-1]
        if None is not defaultItem:
            movieUrls.insert(0, defaultItem)
        if None is not cacheItem:
            movieUrls.insert(0, cacheItem)
        return movieUrls

    def parserIITV(self, url):
        if "streamo" in url:
            match = re.compile("url: '(.+?)',").findall(self.cm.getPage(url)[1])
        if "nonlimit" in url:
            match = re.compile('url: "(.+?)",     provider:').findall(self.cm.getPage(url + ".html?i&e&m=iitv")[1])
        if len(match) > 0:
            linkVideo = match[0]
            printDBG("linkVideo " + linkVideo)
            return linkVideo
        return False

    def parserQFER(self, url):
        match = re.compile('"PSST",url: "(.+?)"').findall(self.cm.getPage(url)[1])
        if len(match) > 0:
            linkVideo = match[0]
            printDBG("linkVideo " + linkVideo)
            return linkVideo
        return False

    def parserYOUTUBE(self, url):
        def __getLinkQuality(itemLink):
            val = itemLink["format"].split("x", 1)[0].split("p", 1)[0]
            try:
                val = int(val) if "x" in itemLink["format"] else int(val) - 1
                return val
            except Exception:
                return 0

        if None is not self.getYTParser():
            try:
                formats = config.plugins.iptvplayer.ytformat.value
                height = config.plugins.iptvplayer.ytDefaultformat.value
                dash = self.getYTParser().isDashAllowed()
                vp9 = self.getYTParser().isVP9Allowed()
                age = self.getYTParser().isAgeGateAllowed()
            except Exception:
                printDBG("parserYOUTUBE default ytformat or ytDefaultformat not available here")
                formats = "mp4"
                height = "360"
                dash = False
                vp9 = False
                age = False
            tmpTab, dashTab = self.getYTParser().getDirectLinks(url, formats, dash, dashSepareteList=True, allowVP9=vp9, allowAgeGate=age)
            videoUrls = []
            for item in tmpTab:
                url = strwithmeta(item["url"], {"youtube_id": item.get("id", "")})
                videoUrls.append({"name": "YouTube | {0}: {1}".format(item["ext"], item["format"]), "url": url, "format": item.get("format", "")})
            for item in dashTab:
                url = strwithmeta(item["url"], {"youtube_id": item.get("id", "")})
                if item.get("ext", "") == "mpd":
                    videoUrls.append({"name": "YouTube | dash: " + item["name"], "url": url, "format": item.get("format", "")})
                else:
                    videoUrls.append({"name": "YouTube | custom dash: " + item["format"], "url": url, "format": item.get("format", "")})
            videoUrls = CSelOneLink(videoUrls, __getLinkQuality, int(height)).getSortedLinks()
            return videoUrls
        return False

    def parserSPRUTOTV(self, baseUrl):
        printDBG("parserSPRUTOTV baseUrl[%r]" % baseUrl)
        sts, data = self.cm.getPage(baseUrl)
        if not sts:
            return False
        return self._findLinks(data, serverName="spruto.tv", linkMarker=r"""['"]?file['"]?[ ]*:[ ]*['"](http[^"^']+)['"][,}]""", m1="Uppod(", m2=")", contain=".mp4")

    def parserOVVATV(self, baseUrl):
        printDBG("parserOVVATV baseUrl[%r]" % baseUrl)
        sts, data = self.cm.getPage(baseUrl)
        if not sts:
            return False
        data = self.cm.ph.getDataBeetwenMarkers(data, "ovva(", ")", False)[1].strip()[1:-1]
        data = json_loads(base64.b64decode(data))
        url = data["url"]
        sts, data = self.cm.getPage(url)
        if not sts:
            return False
        data = data.strip()
        if data.startswith("302="):
            url = data[4:]
        return getDirectM3U8Playlist(url, checkContent=True)[::-1]

    def parserSTREAMMOE(self, baseUrl):
        printDBG("parserSTREAMMOE baseUrl[%r]" % baseUrl)
        HTTP_HEADER = {"User-Agent": "Mozilla/5.0", "Referer": baseUrl}
        url = baseUrl
        sts, data = self.cm.getPage(url, {"header": HTTP_HEADER})
        if not sts:
            return False
        data = re.sub(r"""atob\(["']([^"^']+?)['"]\)""", lambda m: base64.b64decode(m.group(1)), data)
        tab = self._findLinks(data, "stream.moe", linkMarker=r"""['"]?url['"]?[ ]*:[ ]*['"](http[^"^']+(?:\.mp4|\.flv)[^"^']*)['"][,}]""", m1="clip:")
        if len(tab) == 0:
            data = self.cm.ph.getAllItemsBeetwenMarkers(data, "<source", ">", False, False)
            for item in data:
                if "video/mp4" in item:
                    url = self.cm.ph.getSearchGroups(item, """src=['"]([^"^']+?)['"]""")[0]
                    tab.append({"name": "stream.moe", "url": url})
            return tab

    def parserFILEONETV(self, baseUrl):
        printDBG("parserFILEONETV baseUrl[%s]" % baseUrl)
        url = baseUrl.replace("show/player", "v")
        sts, data = self.cm.getPage(url)
        if not sts:
            return False
        tmp = self.cm.ph.getDataBeetwenMarkers(data, "setup({", "});", True)[1]
        videoUrl = self.cm.ph.getSearchGroups(tmp, """file[^"^']+?["'](https?://[^"^']+?)['"]""")[0]
        if videoUrl == "":
            videoUrl = self.cm.ph.getSearchGroups(data, r"""<source[^>]+?src=([^'^"]+?)\s[^>]*?video/mp4""")[0]
        if videoUrl.startswith("//"):
            videoUrl = "https:" + videoUrl
        if self.cm.isValidUrl(videoUrl):
            return videoUrl
        return False

    def parserUSERSCLOUDCOM(self, baseUrl):
        printDBG("parserUSERSCLOUDCOM baseUrl[%s]\n" % baseUrl)
        HTTP_HEADER = {"User-Agent": "Mozilla/5.0 (Linux; U; Android 4.1.1; en-us; androVM for VirtualBox ('Tablet' version with phone caps) Build/JRO03S) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Safari/534.30"}
        COOKIE_FILE = GetCookieDir("userscloudcom.cookie")
        rm(COOKIE_FILE)
        params = {"header": HTTP_HEADER, "cookiefile": COOKIE_FILE, "use_cookie": True, "save_cookie": True, "load_cookie": True}
        sts, data = self.cm.getPage(baseUrl, params)
        cUrl = self.cm.meta["url"]
        errorTab = ["File Not Found", "File was deleted"]
        for errorItem in errorTab:
            if errorItem in data:
                SetIPTVPlayerLastHostError(_(errorItem))
                break
        tmp = self.cm.ph.getDataBeetwenMarkers(data, '<div id="player_code"', "</div>", True)[1]
        tmp = self.cm.ph.getDataBeetwenMarkers(tmp, ">eval(", "</script>")[1]
        # unpack and decode params from JS player script code
        tmp = unpackJSPlayerParams(tmp, VIDUPME_decryptPlayerParams)
        if tmp is not None:
            data = tmp + data
        videoUrl = self.cm.ph.getSearchGroups(data, r"""['"]?file['"]?[ ]*:[ ]*['"]([^"^']+)['"],""")[0]
        if self.cm.isValidUrl(videoUrl):
            return videoUrl
        videoUrl = self.cm.ph.getSearchGroups(data, """<source[^>]+?src=['"]([^'^"]+?)['"][^>]+?["']video""")[0]
        if self.cm.isValidUrl(videoUrl):
            return videoUrl
        sts, data = self.cm.ph.getDataBeetwenMarkers(data, 'method="POST"', "</Form>", False, False)
        if not sts:
            return False
        post_data = dict(re.findall(r'<input[^>]*name="([^"]*)"[^>]*value="([^"]*)"[^>]*>', data))
        params["header"]["Referer"] = cUrl
        params["max_data_size"] = 0
        sts, data = self.cm.getPage(cUrl, params, post_data)
        if sts and "text" not in self.cm.meta["content-type"]:
            return self.cm.meta["url"]

    def parserSTREAMABLECOM(self, baseUrl):
        printDBG("parserSTREAMABLECOM baseUrl[%r]" % baseUrl)
        sts, data = self.cm.getPage(baseUrl)
        if not sts:
            return False
        videoUrl = self.cm.ph.getSearchGroups(data, """<source[^>]+?src=['"]([^'^"]+?)['"][^>]+?video/mp4""")[0]
        if videoUrl == "":
            tmp = re.compile(r"""sourceTag\.src\s*?=\s*?['"]([^'^"]+?)['"]""").findall(data)
            for item in tmp:
                if "mobile" not in item:
                    videoUrl = item
                    break
            if videoUrl == "" and len(tmp):
                videoUrl = tmp[-1]
        if videoUrl == "":
            videoUrl = self.cm.ph.getSearchGroups(data, """<video[^>]+?src=['"]([^'^"]+?)['"]""")[0]
            if videoUrl.split("?", 1)[0].split(".")[-1].lower() != "mp4":
                videoUrl = ""
        if videoUrl.startswith("//"):
            videoUrl = "https:" + videoUrl
        if self.cm.isValidUrl(videoUrl):
            return videoUrl.replace("&amp;", "&")
        msg = clean_html(self.cm.ph.getDataBeetwenNodes(data, ("<div", ">", "content"), ("</div", ">"))[1])
        SetIPTVPlayerLastHostError(msg)
        printDBG("++++++++++++++++++++++++++++++++++++++++++++++++++++++ " + msg)
        return False

    def parserUEFACOM(self, baseUrl):
        printDBG("parserUEFACOM baseUrl[%r]" % baseUrl)
        vid = ph.search(baseUrl, "vid=([0-9]+)")[0]
        if len(vid) % 2 > 0:
            vid = "0" + vid
        vidPart = []
        for idx in range(0, len(vid), 2):
            vidPart.append("n%s=%s" % (len(vidPart) + 1, vid[idx:idx + 2]))
        url = "https://www.uefa.com/library/common/video/%s/feed.js" % ("/").join(vidPart)
        urlParams = {"header": self.cm.getDefaultHeader(browser="chrome")}
        sts, data = self.cm.getPage(baseUrl, urlParams)
        if not sts:
            return False
        token = ph.clean_html(ph.find(data, ("<div", ">", "token"), "</div>", flags=0)[1])
        sts, data = self.cm.getPage(url, urlParams)
        if not sts:
            return False
        cUrl = self.cm.meta["url"]
        streamUrl = ph.search(data, r"""["']([^'^"]+?\.m3u8(?:\?[^"^']+?)?)["']""", flags=0)[0] + "?hdnea=" + token
        streamUrl = strwithmeta(self.cm.getFullUrl(streamUrl, cUrl), {"Referer": cUrl, "User-Agent": urlParams["header"]["User-Agent"]})
        return getDirectM3U8Playlist(streamUrl, checkContent=True, sortWithMaxBitrate=999999999)

    def parserVIDUPLAYERCOM(self, baseUrl):
        printDBG("parserVIDUPLAYERCOM baseUrl[%r]" % baseUrl)
        baseUrl = strwithmeta(baseUrl)
        HTTP_HEADER = self.cm.getDefaultHeader(browser="chrome")
        referer = baseUrl.meta.get("Referer")
        if referer:
            HTTP_HEADER["Referer"] = referer
        sts, data = self.cm.getPage(baseUrl, {"header": HTTP_HEADER})
        if not sts:
            return False
        jscode = [self.jscode["jwplayer"]]
        jscode.append("LevelSelector={};var element=function(n){print(JSON.stringify(n)),this.on=function(){}},Clappr={};Clappr.Player=element,Clappr.Events={PLAYER_READY:1,PLAYER_TIMEUPDATE:1,PLAYER_PLAY:1,PLAYER_ENDED:1};")
        tmp = ph.findall(data, ("<script", ">"), "</script>", flags=0)
        for item in tmp:
            if "eval(" in item:
                jscode.append(item)
        urltab = []
        ret = js_execute(("\n").join(jscode))
        data = json_loads(ret["data"].strip())
        for item in data["sources"]:
            url = item.get("file", "")
            label = item.get("label", "")
            if "m3u8" in url:
                urltab.extend(getDirectM3U8Playlist(url, checkContent=True, sortWithMaxBitrate=999999999))
            elif "mp4" in url:
                urltab.append({"name": "res: " + label, "url": url})
        return urltab

    def parserUPZONECC(self, baseUrl):
        printDBG("parserUPZONECC baseUrl[%r]" % baseUrl)
        baseUrl = strwithmeta(baseUrl)
        HTTP_HEADER = self.cm.getDefaultHeader(browser="chrome")
        referer = baseUrl.meta.get("Referer")
        if referer:
            HTTP_HEADER["Referer"] = referer
        sts, data = self.cm.getPage(baseUrl, {"header": HTTP_HEADER})
        if not sts:
            return False
        cUrl = self.cm.meta["url"]
        if "/embed" not in cUrl:
            url = self.cm.getFullUrl("/embed/" + cUrl.rsplit("/", 1)[(-1)], cUrl)
            sts, tmp = self.cm.getPage(baseUrl, {"header": HTTP_HEADER})
            if not sts:
                return False
            data += tmp
            cUrl = self.cm.meta["url"]
        data = ph.search(data, """['"]([a-zA-Z0-9=]{128,512})['"]""")[0]
        js_params = [{"path": GetJSScriptFile("upzonecc.byte")}]
        js_params.append({"code": "print(cnc(atob('%s')));" % data})
        ret = js_execute_ext(js_params)
        url = self.cm.getFullUrl(ret["data"].strip(), cUrl)
        return strwithmeta(url, {"Referer": cUrl, "User-Agent": HTTP_HEADER["User-Agent"]})

    def parserVEUCLIPS(self, baseUrl):
        printDBG("parserVEUCLIPS baseUrl[%r]" % baseUrl)
        baseUrl = strwithmeta(baseUrl)
        HTTP_HEADER = self.cm.getDefaultHeader(browser="chrome")
        referer = baseUrl.meta.get("Referer")
        if referer:
            HTTP_HEADER["Referer"] = referer
        COOKIE_FILE = GetCookieDir("veuclips.com.cookie")
        rm(COOKIE_FILE)
        urlParams = {"header": HTTP_HEADER, "use_cookie": True, "save_cookie": True, "load_cookie": True, "cookiefile": COOKIE_FILE}
        aObj = re.compile("""<a[^>]+?href=(['"])([^>]*?/player/[^>]*?)(?:\1)""", re.I)
        url = baseUrl
        tries = 0
        while tries < 3:
            tries += 1
            sts, data = self.cm.getPage(url, urlParams)
            if not sts:
                return False
            cUrl = self.cm.meta["url"]
            if "/embed/" in cUrl:
                break
            urlParams["header"].update({"Referer": cUrl})
            url = ph.search(data, ph.IFRAME)[1]
            if not url:
                url = ph.search(data, aObj)[1]
            url = self.cm.getFullUrl(url.replace("&amp;", "&"), cUrl)
        urltab = []
        data = re.compile(r"""["']((?:https?:)?//[^'^"]+?\.m3u8(?:\?[^"^']+?)?)["']""", re.I).findall(data)
        meta = {"Referer": cUrl, "Origin": self.cm.getBaseUrl(cUrl)[:-1], "User-Agent": HTTP_HEADER["User-Agent"]}
        uniqueUrls = set()
        for hlsUrl in data:
            if hlsUrl in uniqueUrls:
                continue
            uniqueUrls.add(hlsUrl)
            hlsUrl = strwithmeta(self.cm.getFullUrl(hlsUrl.replace("&amp;", "&"), cUrl), meta)
            urltab.extend(getDirectM3U8Playlist(hlsUrl, checkContent=True, sortWithMaxBitrate=999999999))
        return urltab

    def parserPROMPTFILE(self, baseUrl):
        printDBG("parserPROMPTFILE baseUrl[%s]" % baseUrl)
        sts, data = self.cm.getPage(baseUrl)
        if sts:
            HTTP_HEADER = dict(self.HTTP_HEADER)
            HTTP_HEADER["Referer"] = baseUrl
            if "Continue to File" in data:
                sts, data = self.cm.ph.getDataBeetwenMarkers(data, '<form method="post" action="">', "</form>", False, False)
                post_data = dict(re.findall(r'<input[^>]*name="([^"]*)"[^>]*value="([^"]*)"[^>]*>', data))
                params = {"header": HTTP_HEADER, "cookiefile": GetCookieDir("promptfile.cookie"), "use_cookie": True, "save_cookie": True, "load_cookie": False}
                sts, data = self.cm.getPage(baseUrl, params, post_data)
                if not sts:
                    return False
            data = self.cm.ph.getSearchGroups(data, """url: ["'](http[^"']+?)["'],""")[0]
            if data != "":
                return data
        return False

    def parserMOVRELLCOM(self, baseUrl):
        printDBG("parserMOVRELLCOM baseUrl[%s]" % baseUrl)
        sts, data = self.cm.getPage(baseUrl)
        if sts:
            HTTP_HEADER = dict(self.HTTP_HEADER)
            HTTP_HEADER["Referer"] = baseUrl
            if "Watch as Free User" in data:
                sts, data = self.cm.ph.getDataBeetwenMarkers(data, "<form", "</form>", False, False)
                post_data = dict(re.findall(r'<input[^>]*name="([^"]*)"[^>]*value="([^"]*)"[^>]*>', data))
                params = {"header": HTTP_HEADER}
                sts, data = self.cm.getPage(baseUrl, params, post_data)
                if not sts:
                    return False
            # get JS player script code from confirmation page
            sts, tmp = self.cm.ph.getDataBeetwenMarkers(data, '<div id="player_code"', "</div>", True)
            sts, tmp = self.cm.ph.getDataBeetwenMarkers(tmp, ">eval(", "</script>")
            if sts:
                # unpack and decode params from JS player script code
                data = unpackJSPlayerParams(tmp, VIDUPME_decryptPlayerParams)
                # get direct link to file from params
                src = self.cm.ph.getSearchGroups(data, 'src="([^"]+?)"')[0]
                if src.startswith("http"):
                    return src
        return False

    def parser1FICHIERCOM(self, baseUrl):
        printDBG("parser1FICHIERCOM baseUrl[%s]" % baseUrl)
        HTTP_HEADER = {
            "User-Agent": "Mozilla/%s%s" % (pageParser.FICHIER_DOWNLOAD_NUM, pageParser.FICHIER_DOWNLOAD_NUM),
            "Accept": "*/*",
            "Accept-Language": "pl,en-US;q=0.7,en;q=0.3",
            "Accept-Encoding": "gzip, deflate",
        }
        pageParser.FICHIER_DOWNLOAD_NUM += 1
        COOKIE_FILE = GetCookieDir("1fichiercom.cookie")
        params = {"header": HTTP_HEADER, "cookiefile": COOKIE_FILE, "use_cookie": True, "load_cookie": True, "save_cookie": True}
        rm(COOKIE_FILE)
        login = config.plugins.iptvplayer.fichiercom_login.value
        password = config.plugins.iptvplayer.fichiercom_password.value
        logedin = False
        if login != "" and password != "":
            url = "https://1fichier.com/login.pl"
            post_data = {"mail": login, "pass": password, "lt": "on", "purge": "on", "valider": "Send"}
            params["header"]["Referer"] = url
            sts, data = self.cm.getPage(url, params, post_data)
            if sts:
                if "My files" in data:
                    logedin = True
                else:
                    error = clean_html(self.cm.ph.getDataBeetwenMarkers(data, '<div class="bloc2"', "</div>")[1])
                    sessionEx = MainSessionWrapper()
                    sessionEx.waitForFinishOpen(MessageBox, _("Login on {0} failed.").format("https://1fichier.com/") + "\n" + error, type=MessageBox.TYPE_INFO, timeout=5)
        sts, data = self.cm.getPage(baseUrl, params)
        if not sts:
            return False
        error = clean_html(self.cm.ph.getDataBeetwenNodes(data, ("<div", ">", "bloc"), ("</div", ">"), False)[1])
        if error != "":
            SetIPTVPlayerLastHostError(error)
        data = self.cm.ph.getDataBeetwenNodes(data, ("<form", ">", "post"), ("</form", ">"), caseSensitive=False)[1]
        printDBG("++++")
        action = self.cm.ph.getSearchGroups(data, """action=['"]([^'^"]+?)['"]""", ignoreCase=True)[0]
        tmp = self.cm.ph.getAllItemsBeetwenMarkers(data, "<input", ">", caseSensitive=False)
        all_post_data = {}
        for item in tmp:
            name = self.cm.ph.getSearchGroups(item, """name=['"]([^'^"]+?)['"]""", ignoreCase=True)[0]
            value = self.cm.ph.getSearchGroups(item, """value=['"]([^'^"]+?)['"]""", ignoreCase=True)[0]
            all_post_data[name] = value
        if "use_credits" in data:
            all_post_data["use_credits"] = "on"
            logedin = True
        else:
            logedin = False
        error = clean_html(self.cm.ph.getDataBeetwenMarkers(data, '<span style="color:red">', "</div>")[1])
        if error != "" and not logedin:
            timeout = self.cm.ph.getSearchGroups(error, r"""wait\s+([0-9]+)\s+([a-zA-Z]{3})""", 2, ignoreCase=True)
            printDBG(timeout)
            if timeout[1].lower() == "min":
                timeout = int(timeout[0]) * 60
            elif timeout[1].lower() == "sec":
                timeout = int(timeout[0])
            else:
                timeout = 0
            printDBG(timeout)
            if timeout > 0:
                sessionEx = MainSessionWrapper()
                sessionEx.waitForFinishOpen(MessageBox, error, type=MessageBox.TYPE_INFO, timeout=timeout)
            else:
                SetIPTVPlayerLastHostError(error)
        else:
            SetIPTVPlayerLastHostError(error)
        post_data = {"dl_no_ssl": "on", "adzone": all_post_data["adzone"]}
        action = urljoin(baseUrl, action)
        if logedin:
            params["max_data_size"] = 0
            params["header"]["Referer"] = baseUrl
            sts = self.cm.getPage(action, params, post_data)[0]
            if not sts:
                return False
            if "text" not in self.cm.meta.get("content-type", ""):
                videoUrl = self.cm.meta["url"]
            else:
                SetIPTVPlayerLastHostError(error)
                videoUrl = ""
        else:
            params["header"]["Referer"] = baseUrl
            sts, data = self.cm.getPage(action, params, post_data)
            if not sts:
                return False
            videoUrl = self.cm.ph.getSearchGroups(data, """<a[^>]+?href=['"](https?://[^'^"]+?)['"][^>]+?ok btn-general""")[0]
        error = clean_html(self.cm.ph.getDataBeetwenNodes(data, ("<div", ">", "bloc"), ("</div", ">"), False)[1])
        if error != "":
            SetIPTVPlayerLastHostError(error)
        printDBG(">>> videoUrl[%s]" % videoUrl)
        if self.cm.isValidUrl(videoUrl):
            return videoUrl
        return False

    def parserFILECLOUDIO(self, baseUrl):
        printDBG("parserFILECLOUDIO baseUrl[%s]" % baseUrl)
        baseUrl = strwithmeta(baseUrl)
        referer = baseUrl.meta.get("Referer", baseUrl)
        HTTP_HEADER = self.cm.getDefaultHeader(browser="chrome")
        if referer != "":
            HTTP_HEADER["Referer"] = referer
        paramsUrl = {"header": HTTP_HEADER, "with_metadata": True}
        sts, data = self.cm.getPage(baseUrl, paramsUrl)
        if not sts:
            return False
        cUrl = data.meta["url"]
        sitekey = self.cm.ph.getSearchGroups(data, r"""['"]?sitekey['"]?\s*?:\s*?['"]([^"^']+?)['"]""")[0]
        if sitekey != "":
            obj = UnCaptchaReCaptcha(lang=GetDefaultLang())
            obj.HTTP_HEADER.update({"Referer": cUrl, "User-Agent": HTTP_HEADER["User-Agent"]})
            token = obj.processCaptcha(sitekey)
            if token == "":
                return False
        else:
            token = ""
        requestUrl = self.cm.ph.getSearchGroups(data, r"""requestUrl\s*?=\s*?['"]([^'^"]+?)['"]""", ignoreCase=True)[0]
        requestUrl = self.cm.getFullUrl(requestUrl, self.cm.getBaseUrl(cUrl))
        data = self.cm.ph.getDataBeetwenMarkers(data, "$.ajax(", ")", caseSensitive=False)[1]
        data = self.cm.ph.getSearchGroups(data, r"""data['"]?:\s*?(\{[^\}]+?\})""", ignoreCase=True)[0]
        data = data.replace("response", '"%s"' % token).replace("'", '"')
        post_data = json_loads(data)
        paramsUrl["header"].update({"Referer": cUrl, "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", "X-Requested-With": "XMLHttpRequest"})
        sts, data = self.cm.getPage(requestUrl, paramsUrl, post_data)
        if not sts:
            return False
        data = json_loads(data)
        if self.cm.isValidUrl(data["downloadUrl"]):
            return strwithmeta(data["downloadUrl"], {"Referer": cUrl, "User-Agent": HTTP_HEADER["User-Agent"]})
        return False

    def parserGOOGLE(self, baseUrl):
        printDBG("parserGOOGLE baseUrl[%s]" % baseUrl)
        urltab = []
        _VALID_URL = r"https?://(?:(?:docs|drive)\.google\.com/(?:uc\?.*?id=|file/d/)|video\.google\.com/get_player\?.*?docid=)(?P<id>[a-zA-Z0-9_-]{28,})"
        mobj = re.match(_VALID_URL, baseUrl)
        try:
            video_id = mobj.group("id")
            linkUrl = "https://docs.google.com/file/d/" + video_id
        except Exception:
            linkUrl = baseUrl
        _FORMATS_EXT = {
            "5": "flv",
            "6": "flv",
            "13": "3gp",
            "17": "3gp",
            "18": "mp4",
            "22": "mp4",
            "34": "flv",
            "35": "flv",
            "36": "3gp",
            "37": "mp4",
            "38": "mp4",
            "43": "webm",
            "44": "webm",
            "45": "webm",
            "46": "webm",
            "59": "mp4",
        }
        HTTP_HEADER = self.cm.getDefaultHeader(browser="chrome")
        HTTP_HEADER["Referer"] = linkUrl
        COOKIE_FILE = GetCookieDir("google.cookie")
        defaultParams = {"header": HTTP_HEADER, "use_cookie": True, "load_cookie": False, "save_cookie": True, "cookiefile": COOKIE_FILE}
        sts, data = self.cm.getPage(linkUrl, defaultParams)
        if not sts:
            return False
        cookieHeader = self.cm.getCookieHeader(COOKIE_FILE)
        fmtDict = {}
        fmtList = self.cm.ph.getSearchGroups(data, '"fmt_list"[:,]"([^"]+?)"')[0]
        fmtList = fmtList.split(",")
        for item in fmtList:
            item = self.cm.ph.getSearchGroups(item, "([0-9]+?)/([0-9]+?x[0-9]+?)/", 2)
            if item[0] != "" and item[1] != "":
                fmtDict[item[0]] = item[1]
        data = self.cm.ph.getSearchGroups(data, '"fmt_stream_map"[:,]"([^"]+?)"')[0]
        data = data.split(",")
        for item in data:
            item = item.split("|")
            printDBG(">> type[%s]" % item[0])
            if "mp4" in _FORMATS_EXT.get(item[0], ""):
                try:
                    quality = int(fmtDict.get(item[0], "").split("x", 1)[-1])
                except Exception:
                    quality = 0
                urltab.append({"name": "drive.google.com: %s" % fmtDict.get(item[0], "").split("x", 1)[-1] + "p", "quality": quality, "url": strwithmeta(unicode_escape(item[1]), {"Cookie": cookieHeader, "Referer": "https://youtube.googleapis.com/", "User-Agent": HTTP_HEADER["User-Agent"]})})
        urltab.sort(key=lambda item: item["quality"], reverse=True)
        return urltab

    def parserARCHIVEORG(self, linkUrl):
        printDBG("parserARCHIVEORG linkUrl[%s]" % linkUrl)
        urltab = []
        sts, data = self.cm.getPage(linkUrl)
        if sts:
            data = self.cm.ph.getSearchGroups(data, r'"sources":\[([^]]+?)]')[0]
            data = "[%s]" % data
            try:
                data = json_loads(data)
                for item in data:
                    if item["type"] == "mp4":
                        urltab.append({"name": "archive.org: " + item["label"], "url": "https://archive.org" + item["file"]})
            except Exception:
                printExc()
        return urltab

    def parserWEBCAMERAPL(self, baseUrl):
        printDBG("parserWEBCAMERAPL baseUrl[%s]" % baseUrl)
        sts, data = self.cm.getPage(baseUrl)
        if not sts:
            return False
        tmp = self.cm.ph.getSearchGroups(data, """stream-player__video['"] data-src=['"]([^"^']+?)['"]""")[0]
        if tmp == "":
            tmp = self.cm.ph.getSearchGroups(data, """STREAM_PLAYER_CONFIG[^}]+?['"]video_src['"]:['"]([^"^']+?)['"]""")[0].replace(r"\/", "/")
        if tmp != "":
            tmp = codecs.decode(tmp, "rot13")
            return getDirectM3U8Playlist(tmp, checkContent=True)
        return False

    def parserTVP(self, baseUrl):
        printDBG("parserTVP baseUrl[%s]" % baseUrl)
        vidTab = []
        try:
            from Plugins.Extensions.IPTVPlayer.hosts.hosttvpvod import TvpVod

            vidTab = TvpVod().getLinksForVideo({"url": baseUrl})
        except Exception:
            printExc()
        return vidTab

    def parserJUNKYVIDEO(self, baseUrl):
        printDBG("parserJUNKYVIDEO baseUrl[%s]" % baseUrl)
        sts, data = self.cm.getPage(baseUrl)
        if not sts:
            return []
        url = self.cm.ph.getSearchGroups(data, r"""['"]?file['"]?[ ]*:[ ]*['"]([^"^']+)['"],""")[0]
        if url.startswith("http"):
            return [{"name": "junkyvideo.com", "url": url}]
        return []

    def parserNETTVPLUSCOM(self, baseUrl):
        printDBG("parserNETTVPLUSCOM baseUrl[%s]" % baseUrl)
        HTTP_HEADER = dict(self.HTTP_HEADER)
        HTTP_HEADER["User-Agent"] = "Mozilla/5.0 (Linux; U; Android 4.1.1; en-us; androVM for VirtualBox ('Tablet' version with phone caps) Build/JRO03S) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Safari/534.30"
        HTTP_HEADER["Referer"] = baseUrl
        if baseUrl.endswith("/source.js"):
            url = baseUrl
        else:
            url = baseUrl[: baseUrl.rfind("/")] + "/source.js"
        sts, data = self.cm.getPage(url, {"header": HTTP_HEADER})
        if not sts:
            return []
        url = self.cm.ph.getSearchGroups(data, """["'](http[^'^"]+?m3u8[^'^"]*?)["']""")[0]
        if url != "":
            return getDirectM3U8Playlist(url, False)
        return []

    def parserFACEBOOK(self, baseUrl):
        printDBG("parserFACEBOOK baseUrl[%s]" % baseUrl)
        sts, data = self.cm.getPage(baseUrl)
        if not sts:
            return []
        urlsTab = []
        for item in ["hd_src_no_ratelimit", "hd_src", "sd_src_no_ratelimit", "sd_src"]:
            url = self.cm.ph.getSearchGroups(data, r'''"?%s"?\s*?:\s*?"(http[^"]+?\.mp4[^"]*?)"''' % item)[0]
            url = url.replace("\\/", "/")
            if self.cm.isValidUrl(url):
                urlsTab.append({"name": "facebook %s" % item, "url": url})
        return urlsTab

    def parserXAGEPL(self, baseUrl):
        printDBG("parserXAGEPL baseUrl[%s]" % baseUrl)
        sts, data = self.cm.getPage(baseUrl)
        if not sts:
            return False
        url = self.cm.ph.getSearchGroups(data, 'src="([^"]+?)"')[0]
        return urlparser().getVideoLinkExt(url)

    def parserKABABLIMA(self, baseUrl):
        printDBG("parserKABABLIMA baseUrl[%s]" % baseUrl)
        baseUrl = urlparser.decorateParamsFromUrl(baseUrl)
        Referer = baseUrl.meta.get("Referer", "")
        HTTP_HEADER = dict(self.HTTP_HEADER)
        HTTP_HEADER["Referer"] = Referer
        sts, data = self.cm.getPage(baseUrl, {"header": HTTP_HEADER})
        if not sts:
            return False
        data = re.sub(r"<!--[\s\S]*?-->", "", data)
        data = re.sub(r"/\*[\s\S]*?\*/", "", data)
        hlsUrl = self.cm.ph.getSearchGroups(data, r"""["'](https?://[^'^"]+?\.m3u8(?:\?[^"^']+?)?)["']""", ignoreCase=True)[0]
        if hlsUrl != "":
            return getDirectM3U8Playlist(hlsUrl, checkContent=True)
        return False

    def parserUSTREAMIXCOM(self, baseUrl):
        printDBG("parserUSTREAMIXCOM baseUrl[%s]" % baseUrl)
        baseUrl = urlparser.decorateParamsFromUrl(baseUrl)
        Referer = baseUrl.meta.get("Referer", "")
        HTTP_HEADER = dict(self.HTTP_HEADER)
        HTTP_HEADER["Referer"] = Referer
        sts, data = self.cm.getPage(baseUrl, {"header": HTTP_HEADER})
        if not sts:
            return False
        val = int(self.cm.ph.getSearchGroups(data, r" \- (\d+)")[0])
        data = self.cm.ph.getDataBeetwenMarkers(data, "= [", "]")[1]
        data = self.cm.ph.getAllItemsBeetwenMarkers(data, '"', '"')
        text = ""
        numObj = re.compile(r"(\d+)")
        for value in data:
            value = base64.b64decode(value)
            text += chr(int(numObj.search(value).group(1)) - val)
        statsUrl = self.cm.ph.getSearchGroups(text, r"""src=["'](https?://[^'^"]*?stats\.php[^'^"]*?)["']""", ignoreCase=True)[0]
        HTTP_HEADER["Referer"] = baseUrl
        sts, data = self.cm.getPage(statsUrl, {"header": HTTP_HEADER})
        if not sts:
            return False
        token = self.cm.ph.getAllItemsBeetwenMarkers(data, '"', '"', False)[-1]
        printDBG("token||||||||||||||||| " + token)
        hlsUrl = self.cm.ph.getSearchGroups(text, r"""["'](https?://[^'^"]+?\.m3u8(?:\?[^"^']+?)?)["']""", ignoreCase=True)[0]
        printDBG("hlsUrl||||||||||||||||| " + hlsUrl)
        if hlsUrl != "":
            if hlsUrl.endswith("="):
                hlsUrl += token
            hlsUrl = strwithmeta(hlsUrl, {"Referer": baseUrl})
            return getDirectM3U8Playlist(hlsUrl, checkContent=True)
        return False

    def parseVIMEOCOM(self, baseUrl):
        printDBG("parseVIMEOCOM baseUrl[%s]" % baseUrl)
        if "player" not in baseUrl:
            video_id = self.cm.ph.getSearchGroups(baseUrl + "/", "/([0-9]+?)[/.]")[0]
            if video_id != "":
                url = "https://player.vimeo.com/video/" + video_id
            else:
                sts, data = self.cm.getPage(baseUrl)
                if not sts:
                    return False
                url = self.cm.ph.getSearchGroups(data, r"""['"]embedUrl['"]\s*?:\s*?['"]([^'^"]+?)['"]""")[0]
        else:
            url = baseUrl
        baseUrl = strwithmeta(baseUrl)
        HTTP_HEADER = self.cm.getDefaultHeader(browser="chrome")
        if "Referer" in baseUrl.meta:
            HTTP_HEADER["Referer"] = baseUrl.meta["Referer"]
        sts, data = self.cm.getPage(url, {"header": HTTP_HEADER})
        if not sts:
            return False
        urltab = []
        tmp = self.cm.ph.getDataBeetwenMarkers(data, "progressive", "]", False)[1]
        tmp = tmp.split("}")
        printDBG(tmp)
        for item in tmp:
            if "video/mp4" not in item:
                continue
            quality = self.cm.ph.getSearchGroups(item, """quality['"]?:['"]([^"^']+?)['"]""")[0]
            url = self.cm.ph.getSearchGroups(item, """url['"]?:['"]([^"^']+?)['"]""")[0]
            if url.startswith("http"):
                urltab.append({"name": "vimeo.com {0}".format(quality), "url": url})
        hlsUrl = self.cm.ph.getSearchGroups(data, r'"hls"[^}]+?"url"\:"([^"]+?)"')[0]
        tab = getDirectM3U8Playlist(hlsUrl)
        urltab.extend(tab)
        return urltab

    def parserTINYCC(self, baseUrl):
        printDBG("parserTINYCC baseUrl[%s]" % baseUrl)
        self.cm.getPage(baseUrl, {"max_data_size": 0})
        redirectUrl = self.cm.meta["url"]
        if baseUrl != redirectUrl:
            return urlparser().getVideoLinkExt(redirectUrl)
        return False

    def parserONETTV(self, baseUrl):
        printDBG("parserONETTV baseUrl[%r]" % baseUrl)
        videoUrls = []
        sts, data = self.cm.getPage(baseUrl)
        if not sts:
            return videoUrls
        ckmId = self.cm.ph.getSearchGroups(data, 'data-params-mvp="([^"]+?)"')[0]
        if ckmId == "":
            ckmId = self.cm.ph.getSearchGroups(data, 'id="mvp:([^"]+?)"')[0]
        if ckmId == "":
            return videoUrls
        tm = str(int(time.time() * 1000))
        jQ = str(randrange(562674473039806, 962674473039806))
        authKey = "FDF9406DE81BE0B573142F380CFA6043"
        hostName = urlparser().getHostName(baseUrl)
        # TODO: the page is down
        contentUrl = "http://qi.ckm.onetapi.pl/?callback=jQuery183040" + jQ + "_" + tm + "&body%5Bid%5D=" + authKey + "&body%5Bjsonrpc%5D=2.0&body%5Bmethod%5D=get_asset_detail&body%5Bparams%5D%5BID_Publikacji%5D=" + ckmId + "&body%5Bparams%5D%5BService%5D={0}&content-type=application%2Fjsonp&x-onet-app=player.front.onetapi.pl&_=".format(hostName) + tm
        sts, data = self.cm.getPage(contentUrl)
        if sts:
            try:
                data = json_loads(data[data.find("(") + 1:-2])
                data = data["result"]["0"]["formats"]["wideo"]
                for typ in data:
                    for vidItem in data[typ]:
                        if None is not vidItem.get("drm_key", None):
                            continue
                        vidUrl = vidItem.get("url", "")
                        if vidUrl == "":
                            continue
                        if typ == "hls":
                            tmpTab = getDirectM3U8Playlist(vidUrl)
                            for tmp in tmpTab:
                                videoUrls.append({"name": "ONET type:%s :%s" % (typ, tmp.get("bitrate", "0")), "url": tmp["url"]})
                        elif None is not vidItem.get("video_bitrate", None):
                            videoUrls.append({"name": "ONET type:%s :%s" % (typ, vidItem.get("video_bitrate", "0")), "url": vidUrl})
                        elif None is not vidItem.get("audio_bitrate", None):
                            videoUrls.append({"name": "ONET type:%s :%s" % (typ, vidItem.get("audio_bitrate", "0")), "url": vidUrl})
            except Exception:
                printExc()
        return videoUrls

    def parserVIDEOHOUSE(self, baseUrl):
        printDBG("parserVIDEOHOUSE baseUrl[%r]" % baseUrl)
        HTTP_HEADER = MergeDicts(self.cm.getDefaultHeader("firefox"), {"Referer": baseUrl})
        sts, data = self.cm.getPage(baseUrl, {"header": HTTP_HEADER})
        if not sts:
            return False
        cUrl = self.cm.meta["url"]
        up = urlparser()
        tmp = ph.IFRAME.findall(data)
        tmp.extend(ph.A.findall(data))
        for item in tmp:
            url = self.cm.getFullUrl(item[1], cUrl)
            if up.checkHostSupport(url) == 1:
                urls = up.getVideoLink(url)
                if urls:
                    return urls
        return False

    def parserJUSTUPLOAD(self, baseUrl):
        printDBG("parserJUSTUPLOAD baseUrl[%r]" % baseUrl)
        HTTP_HEADER = MergeDicts(self.cm.getDefaultHeader("firefox"), {"Referer": baseUrl})
        sts, data = self.cm.getPage(baseUrl, {"header": HTTP_HEADER})
        if not sts:
            return False
        videoUrl = ph.search(data, r"""<source\s*?src=['"]([^'^"]+?)['"]""")[0]
        if videoUrl.startswith("//"):
            videoUrl = "http:" + videoUrl
        return videoUrl

    def parserVEVO(self, baseUrl):
        printDBG("parserVEVO baseUrl[%r]" % baseUrl)
        videoUrls = self.getVevoIE()._real_extract(baseUrl)["formats"]
        for idx in range(len(videoUrls)):
            width = int(videoUrls[idx].get("width", 0))
            height = int(videoUrls[idx].get("height", 0))
            bitrate = int(videoUrls[idx].get("bitrate", 0)) / 8
            name = ""
            if bitrate != 0:
                name = "bitrate %s" % (formatBytes(bitrate, 0).replace(".0", "") + "/s")
            if width != 0 or height != 0:
                name += " %sx%s" % (width, height)
            if name == "":
                name = "%s." % (idx + 1)
            videoUrls[idx]["name"] = name
        if len(videoUrls) > 0:
            max_bitrate = int(config.plugins.iptvplayer.vevo_default_quality.value)

            def __getLinkQuality(itemLink):
                return int(itemLink["bitrate"])

            videoUrls = CSelOneLink(videoUrls, __getLinkQuality, max_bitrate).getSortedLinks()
            if config.plugins.iptvplayer.vevo_use_default_quality.value:
                videoUrls = [videoUrls[0]]
        return videoUrls

    def parserBBC(self, baseUrl):
        printDBG("parserBBC baseUrl[%r]" % baseUrl)
        vpid = self.cm.ph.getSearchGroups(baseUrl, "/vpid/([^/]+?)/")[0]
        if vpid == "":
            data = self.getBBCIE()._real_extract(baseUrl)
        else:
            formats, subtitles = self.getBBCIE()._download_media_selector(vpid)
            data = {"formats": formats, "subtitles": subtitles}
        subtitlesTab = []
        for sub in data.get("subtitles", []):
            if self.cm.isValidUrl(sub.get("url", "")):
                subtitlesTab.append({"title": _(sub["lang"]), "url": sub["url"], "lang": sub["lang"], "format": sub["ext"]})
        videoUrls = []
        hlsLinks = []
        mpdLinks = []
        for vidItem in data["formats"]:
            if "url" in vidItem:
                url = self.getBBCIE().getFullUrl(vidItem["url"].replace("&amp;", "&"))
                if vidItem.get("ext", "") == "hls" and len(hlsLinks) == 0:
                    hlsLinks.extend(getDirectM3U8Playlist(url, False, checkContent=True))
                elif vidItem.get("ext", "") == "mpd" and len(mpdLinks) == 0:
                    mpdLinks.extend(getMPDLinksWithMeta(url, False))
        tmpTab = [hlsLinks, mpdLinks]
        if config.plugins.iptvplayer.bbc_prefered_format.value == "dash":
            tmpTab.reverse()
        max_bitrate = int(config.plugins.iptvplayer.bbc_default_quality.value)
        for item in tmpTab:

            def __getLinkQuality(itemLink):
                try:
                    return int(itemLink["height"])
                except Exception:
                    return 0

            item = CSelOneLink(item, __getLinkQuality, max_bitrate).getSortedLinks()
            if config.plugins.iptvplayer.bbc_use_default_quality.value:
                videoUrls.append(item[0])
                break
            videoUrls.extend(item)
        if subtitlesTab:
            for idx in range(len(videoUrls)):
                videoUrls[idx]["url"] = strwithmeta(videoUrls[idx]["url"], {"external_sub_tracks": subtitlesTab})
        return videoUrls

    def parserZEROCASTTV(self, baseUrl):
        printDBG("parserZEROCASTTV baseUrl[%r]" % baseUrl)
        if "embed.php" in baseUrl:
            url = baseUrl
        elif "chan.php?" in baseUrl:
            sts, data = self.cm.getPage(baseUrl)
            if not sts:
                return False
            data = self.cm.ph.getDataBeetwenMarkers(data, "<body ", "</body>", False)[1]
            url = self.cm.ph.getSearchGroups(data, r"""src=['"](http[^"^']+)['"]""")[0]
        if "embed.php" not in url:
            sts, data = self.cm.getPage(url)
            if not sts:
                return False
            url = self.cm.ph.getSearchGroups(data, r"""var [^=]+?=[^'^"]*?['"](http[^'^"]+?)['"];""")[0]
        if url == "":
            return False
        sts, data = self.cm.getPage(url)
        if not sts:
            return False
        channelData = self.cm.ph.getSearchGroups(data, r"""unescape\(['"]([^'^"]+?)['"]\)""")[0]
        channelData = urllib_unquote(channelData)
        if channelData == "":
            data = self.cm.ph.getSearchGroups(data, "<h1[^>]*?>([^<]+?)<")[0]
            SetIPTVPlayerLastHostError(data)
        if channelData.startswith("rtmp"):
            channelData += " live=1 "
            return channelData
        return False

    def parserCASACINEMACC(self, baseUrl):
        printDBG("parserCASACINEMACC url[%s]\n" % baseUrl)
        sts, data = self.cm.getPage(baseUrl)
        if not sts:
            return False
        tmp = self.cm.ph.getDataBeetwenMarkers(data, "eval(", "</script>")[1]
        tmp = unpackJSPlayerParams(tmp, TEAMCASTPL_decryptPlayerParams, type=0)
        data += tmp
        urltab = self._findLinks(data, "casacinema.cc")
        return urltab

    def parserFILEZTV(self, baseUrl):
        printDBG("parserFILEZTV url[%s]\n" % baseUrl)
        sts, data = self.cm.getPage(baseUrl)
        if not sts:
            return False
        data = self.cm.ph.getDataBeetwenMarkers(data, ".setup(", ")", False)[1].strip()
        videoUrl = self.cm.ph.getSearchGroups(data, r"""['"]?file['"]?\s*:\s*['"](http[^'^"]+?)['"]""")[0]
        if self.cm.isValidUrl(videoUrl):
            return videoUrl
        return False

    def parserVSPORTSPT(self, baseUrl):
        printDBG("parserVSPORTSPT baseUrl[%s]\n" % baseUrl)
        urlsTab = []
        sts, data = self.cm.getPage(baseUrl)
        if not sts:
            return []
        if "vsports.videos.sapo.pt" in data:
            videoUrl = re.findall(r"(vsports\.videos\.sapo\.pt/[\w]+/mov/)", data)
            if videoUrl:
                videoUrl = "https://" + videoUrl[0] + "?videosrc=true"
                sts, link = self.cm.getPage(videoUrl)
                if sts:
                    printDBG(" '%s' ---> '%s' " % (videoUrl, link))
                    urlsTab.append({"name": "link", "url": link})
                    return urlsTab
        tmp = self.cm.ph.getDataBeetwenReMarkers(data, re.compile(r"""['"]?sources['"]?\s*:\s*\["""), re.compile(r"\]"), False)[1]
        tmp = tmp.split("}")
        for item in tmp:
            videoUrl = self.cm.ph.getSearchGroups(item, r"""['"]?src['"]?\s*:.*?['"]([^'^"]*?//[^'^"]+?)['"]""")[0]
            typ = self.cm.ph.getSearchGroups(item, r"""['"]?type['"]?\s*:\s*['"]([^'^"]+?)['"]""")[0]
            if videoUrl.startswith("//"):
                videoUrl = "https:" + videoUrl
            if self.cm.isValidUrl(videoUrl):
                urlsTab.append({"name": typ, "url": videoUrl})
        data = self.cm.ph.getDataBeetwenMarkers(data, ".setup(", ");", False)[1].strip()
        videoUrl = self.cm.ph.getSearchGroups(data, r"""['"]?file['"]?\s*:\s*['"]((?:https?:)?//[^"^']+\.mp4)['"]""")[0]
        if videoUrl.startswith("//"):
            videoUrl = "https:" + videoUrl
        if self.cm.isValidUrl(videoUrl):
            urlsTab.append({"name": "direct", "url": videoUrl})
        return urlsTab

    def parserPOLSATSPORTPL(self, baseUrl):
        printDBG("parserPOLSATSPORTPL baseUrl[%s]" % baseUrl)
        baseUrl = strwithmeta(baseUrl)
        domain = urlparser.getDomain(baseUrl)
        sts, data = self.cm.getPage(baseUrl)
        sts, tmp = self.cm.ph.getDataBeetwenMarkers(data, "<video", "</video>")
        if not sts:
            return False
        tmp = self.cm.ph.getAllItemsBeetwenMarkers(tmp, "<source", ">")
        urltab = []
        for item in tmp:
            if "video/mp4" not in item and "video/x-flv" not in item:
                continue
            tType = self.cm.ph.getSearchGroups(item, """type=['"]([^'^"]+?)['"]""")[0].replace("video/", "")
            tUrl = self.cm.ph.getSearchGroups(item, """src=['"]([^'^"]+?)['"]""")[0]
            printDBG(tUrl)
            if self.cm.isValidUrl(tUrl):
                urltab.append({"name": "[%s] %s" % (tType, domain), "url": strwithmeta(tUrl)})
        return urltab

    def parserGAMOVIDEOCOM(self, baseUrl):
        printDBG("parserGAMOVIDEOCOM baseUrl[%s]" % baseUrl)
        baseUrl = strwithmeta(baseUrl)
        referer = baseUrl.meta.get("Referer", "")
        domain = urlparser.getDomain(baseUrl)
        HEADER = self.cm.getDefaultHeader(browser="chrome")
        HEADER["Referer"] = referer
        sts, data = self.cm.getPage(baseUrl, {"header": HEADER})
        if not sts:
            return False
        if "embed" not in self.cm.meta["url"].lower():
            HEADER["Referer"] = self.cm.meta["url"]
            url = self.cm.getFullUrl(self.cm.ph.getSearchGroups(data, """<iframe[^>]+?src=['"]([^"^']+?embed[^"^']+?)['"]""", 1, True)[0], self.cm.meta["url"])
            sts, data = self.cm.getPage(url, {"header": HEADER})
            if not sts:
                return False
        jscode = [self.jscode["jwplayer"]]
        jscode.append("var element=function(n){print(JSON.stringify(n)),this.on=function(){}},Clappr={};Clappr.Player=element,Clappr.Events={PLAYER_READY:1,PLAYER_TIMEUPDATE:1,PLAYER_PLAY:1,PLAYER_ENDED:1};")
        tmp = self.cm.ph.getAllItemsBeetwenNodes(data, ("<script", ">"), ("</script", ">"), False)
        for item in tmp:
            if "eval(" in item and "jwplayer" in item:
                jscode.append(item)
        ret = js_execute("\n".join(jscode))
        if ret["sts"]:
            data += ret["data"]
        urltab = []
        items = self.cm.ph.getAllItemsBeetwenMarkers(data, "<source ", ">", False, False)
        if len(items) == 0:
            items = self.cm.ph.getDataBeetwenReMarkers(data, re.compile(r"""[\s'"]sources[\s'"]*[=:]\s*\["""), re.compile(r"""\]"""), False)[1].split("},")
        printDBG(items)
        for item in items:
            item = item.replace(r"\/", "/")
            url = self.cm.ph.getSearchGroups(item, r"""(?:src|file)['"]?\s*[=:]\s*['"]([^"^']+?)['"]""")[0]
            if not url.lower().split("?", 1)[0].endswith(".mp4") or not self.cm.isValidUrl(url):
                continue
            res = self.cm.ph.getSearchGroups(item, r"""res['"]?\s*[=:]\s*['"]([^"^']+?)['"]""")[0]
            lang = self.cm.ph.getSearchGroups(item, r"""lang['"]?\s*[=:]\s*['"]([^"^']+?)['"]""")[0]
            url = strwithmeta(url, {"Referer": baseUrl})
            urltab.append({"name": domain + " {0} {1}".format(lang, res), "url": url})
        return urltab

    def parserMEDIAFIRECOM(self, baseUrl):
        printDBG("parserMEDIAFIRECOM baseUrl[%s]" % baseUrl)
        HEADER = {"User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.0", "Accept": "*/*", "Accept-Encoding": "gzip, deflate"}
        sts, data = self.cm.getPage(baseUrl, {"header": HEADER})
        if not sts:
            return False
        data = self.cm.ph.getDataBeetwenNodes(data, ("<div", ">", '"download_link"'), ("</div", ">"))[1]
        data = self.cm.ph.getDataBeetwenNodes(data, ("<script", ">"), ("</script", ">"), False)[1]
        jscode = """window=this;document={};document.write=function(){print(arguments[0]);}"""
        ret = js_execute(jscode + "\n" + data)
        if ret["sts"] and ret["code"] == 0:
            videoUrl = self.cm.ph.getSearchGroups(ret["data"], """href=['"]([^"^']+?)['"]""")[0]
            if self.cm.isValidUrl(videoUrl):
                return videoUrl
        return False

    def parserVIDLOADCO(self, baseUrl):
        printDBG("parserVIDLOADCO baseUrl[%r]" % baseUrl)
        baseUrl = strwithmeta(baseUrl)
        cUrl = baseUrl
        HTTP_HEADER = self.cm.getDefaultHeader(browser="chrome")
        HTTP_HEADER["Referer"] = baseUrl.meta.get("Referer", baseUrl)
        urlParams = {"header": HTTP_HEADER}
        sts, data = self.cm.getPage(baseUrl, urlParams)
        if not sts:
            return False
        cUrl = self.cm.meta["url"]
        domain = self.cm.getBaseUrl(cUrl, True)
        urltab = []
        data = self.cm.ph.getAllItemsBeetwenMarkers(data, "sources", "]", False)
        for sourceData in data:
            sourceData = self.cm.ph.getAllItemsBeetwenMarkers(sourceData, "{", "}")
            for item in sourceData:
                marker = item.lower()
                if "video/mp4" not in marker and "video/x-flv" not in marker and "x-mpeg" not in marker:
                    continue
                item = item.replace("\\/", "/")
                url = self.cm.getFullUrl(self.cm.ph.getSearchGroups(item, r"""(?:src|file)['"]?\s*[=:]\s*['"]([^"^']+?)['"]""")[0], self.cm.getBaseUrl(cUrl))
                types = self.cm.ph.getSearchGroups(item, r"""type['"]?\s*[=:]\s*['"]([^"^']+?)['"]""")[0]
                label = self.cm.ph.getSearchGroups(item, r"""type['"]?\s*[=:]\s*['"]([^"^']+?)['"]""")[0]
                printDBG(url)
                if url == "":
                    continue
                url = strwithmeta(url, {"User-Agent": HTTP_HEADER["User-Agent"], "Referer": cUrl})
                if "x-mpeg" in marker:
                    urltab.extend(getDirectM3U8Playlist(url, checkContent=True))
                else:
                    urltab.append({"name": "[%s] %s %s" % (types, domain, label), "url": url})
        return urltab

    def parserSOUNDCLOUDCOM(self, baseUrl):
        printDBG("parserSOUNDCLOUDCOM baseUrl[%r]" % baseUrl)
        baseUrl = strwithmeta(baseUrl)
        cUrl = baseUrl
        HTTP_HEADER = self.cm.getDefaultHeader(browser="chrome")
        HTTP_HEADER["Referer"] = baseUrl.meta.get("Referer", baseUrl)
        urlParams = {"with_metadata": True, "header": HTTP_HEADER}
        sts, data = self.cm.getPage(baseUrl, urlParams)
        if not sts:
            return False
        cUrl = data.meta["url"]
        tarckId = self.cm.ph.getSearchGroups(data, r"""tracks\:([0-9]+)""")[0]
        url = self.cm.ph.getSearchGroups(data, r"""['"](https?://[^'^"]+?/widget\-[^'^"]+?\.js)""")[0]
        sts, data = self.cm.getPage(url, urlParams)
        if not sts:
            return False
        clinetIds = self.cm.ph.getSearchGroups(data, r'''client_id\:[A-Za-z]+?\?"([^"]+?)"\:"([^"]+?)"''', 2)
        baseUrl = "https://api.soundcloud.com/i1/tracks/%s/streams?client_id=" % tarckId
        jsData = None
        for clientId in clinetIds:
            url = baseUrl + clientId
            sts, data = self.cm.getPage(url, urlParams)
            if not sts:
                continue
            try:
                jsData = json_loads(data)
            except Exception:
                printExc()
        urls = []
        baseName = urlparser.getDomain(cUrl)
        for key in jsData:
            if "preview" in key:
                continue
            url = jsData[key]
            if self.cm.isValidUrl(url):
                urls.append({"name": baseName + " " + key, "url": url})
        return urls

    def parserCLOUDSTREAMUS(self, baseUrl):
        printDBG("parserCLOUDSTREAMUS baseUrl[%r]" % baseUrl)
        baseUrl = strwithmeta(baseUrl)
        HTTP_HEADER = self.cm.getDefaultHeader(browser="chrome")
        HTTP_HEADER["Referer"] = baseUrl.meta.get("Referer", baseUrl)
        jscode = ["eval=function(t){return function(){print(arguments[0]);try{return t.apply(this,arguments)}catch(t){}}}(eval);"]
        sts, data = self.cm.getPage(baseUrl, {"header": HTTP_HEADER})
        if not sts:
            return False
        data = self.cm.ph.getAllItemsBeetwenNodes(data, ("<script", ">"), ("</script", ">"), False)
        for item in data:
            if "eval(" in item:
                jscode.append(item)
        ret = js_execute("\n".join(jscode))
        if ret["sts"] and ret["code"] == 0:
            data = ret["data"]
        urlsTab = []
        googleDriveFiles = []
        data = self.cm.ph.getAllItemsBeetwenMarkers(data, "sources:", "],", False)
        for sourceData in data:
            sourceData = self.cm.ph.getAllItemsBeetwenMarkers(sourceData, "{", "}")
            for item in sourceData:
                types = self.cm.ph.getSearchGroups(item, r"""['"\{\,\s]type['"]?\s*:\s*['"]([^'^"]+?)['"]""")[0].lower()
                if types != "mp4":
                    continue
                url = self.cm.ph.getSearchGroups(item, r"""['"\{\,\s]file['"]?\s*:\s*['"]([^'^"]+?)['"]""")[0]
                if "googleapis.com/drive" in url and "/files/" in url:
                    fileId = url.split("/files/", 1)[-1].split("?", 1)[0]
                    if fileId != "":
                        if fileId in googleDriveFiles:
                            continue
                        googleDriveFiles.append(fileId)
                        continue
                name = self.cm.ph.getSearchGroups(item, r"""['"\{\,\s]label['"]?\s*:\s*['"]([^'^"]+?)['"]""")[0]
                if name == "":
                    name = urlparser.getDomain(url)
                urlsTab.append({"name": name, "url": url})
        printDBG(googleDriveFiles)
        for fileId in googleDriveFiles:
            tmp = urlparser().getVideoLinkExt("https://drive.google.com/file/d/%s/view" % fileId)
            if tmp:
                tmp.extend(urlsTab)
                urlsTab = tmp
        return urlsTab

    def parserCLOUDCARTELNET(self, baseUrl):
        printDBG("parserCLOUDCARTELNET baseUrl[%s]" % baseUrl)
        baseUrl = strwithmeta(baseUrl)
        HTTP_HEADER = self.cm.getDefaultHeader()
        if "Referer" in baseUrl.meta:
            HTTP_HEADER["Referer"] = baseUrl.meta["Referer"]
        params = {"header": HTTP_HEADER}
        sts, data = self.cm.getPage(baseUrl, params)
        if not sts:
            return False
        cUrl = self.cm.meta["url"]
        domain = self.cm.getBaseUrl(cUrl)
        videoId = self.cm.ph.getSearchGroups(baseUrl + "/", """(?:/video/|/link/)([^/]+?)/""")[0]
        apiUrl = self.cm.getFullUrl(self.cm.ph.getSearchGroups(data, """<video[^>]+?poster=['"]([^'^"]+?)['"]""")[0], domain)
        apiDomain = self.cm.getBaseUrl(apiUrl)
        url = self.cm.getFullUrl("/download/link/" + videoId, apiDomain)
        sts, data = self.cm.getPage(url, params)
        if not sts:
            return False
        data = json_loads(data)
        if "mp4" in data["content_type"]:
            return self.cm.getFullUrl(data["url"], apiDomain)
        return False

    def parserKRAKENFILESCOM(self, baseUrl):
        printDBG("parserKRAKENFILESCOM baseUrl[%r]" % baseUrl)
        baseUrl = strwithmeta(baseUrl)
        HTTP_HEADER = self.cm.getDefaultHeader(browser="chrome")
        HTTP_HEADER["Referer"] = baseUrl.meta.get("Referer", baseUrl)
        urlParams = {"header": HTTP_HEADER}
        sts, data = self.cm.getPage(baseUrl, urlParams)
        if not sts:
            return False
        cUrl = self.cm.meta["url"]
        domain = urlparser.getDomain(cUrl)
        urltab = []
        data = re.compile(r"""['"]([^'^"]+?/uploads/[^'^"]+?\.(?:m4a|mp3)(?:\?[^'^"]*?)?)['"]""").findall(data)
        for url in data:
            url = strwithmeta(self.cm.getFullUrl(url, self.cm.meta["url"]), {"Referer": baseUrl, "User-Agent": HTTP_HEADER["User-Agent"]})
            urltab.append({"name": "%s %s" % (domain, len(urltab) + 1), "url": url})
        return urltab

    def parserFILEFACTORYCOM(self, baseUrl):
        printDBG("parserFILEFACTORYCOM baseUrl[%r]" % baseUrl)
        baseUrl = strwithmeta(baseUrl)
        HTTP_HEADER = self.cm.getDefaultHeader(browser="chrome")
        HTTP_HEADER["Referer"] = baseUrl.meta.get("Referer", baseUrl)
        urlParams = {"header": HTTP_HEADER}
        sts, data = self.cm.getPage(baseUrl, urlParams)
        if not sts:
            return False
        cUrl = self.cm.meta["url"]
        domain = urlparser.getDomain(cUrl)
        videoUrl = self.cm.getFullUrl(self.cm.ph.getSearchGroups(data, r"""data\-href=['"]([^'^"]+?)['"]""")[0], self.cm.meta["url"])
        if not videoUrl:
            return False
        sleep_time = self.cm.ph.getSearchGroups(data, r"""data\-delay=['"]([0-9]+?)['"]""")[0]
        try:
            GetIPTVSleep().Sleep(int(sleep_time))
        except Exception:
            printExc()
        sts, data = self.cm.getPage(videoUrl, {"max_data_size": 200 * 1024})
        if sts:
            if "text" not in self.cm.meta["content-type"]:
                return [{"name": domain, "url": videoUrl}]
            msg = clean_html(self.cm.ph.getDataBeetwenNodes(data, ("<div", ">", "box-message"), ("</div", ">"), False)[1])
            SetIPTVPlayerLastHostError(msg)
        return False

    def parserMEDIASET(self, baseUrl):
        printDBG("parserMEDIASET baseUrl[%r]" % baseUrl)
        guid = ph.search(baseUrl, r"""https?://(?:(?:www|static3)\.)?mediasetplay\.mediaset\.it/(?:(?:video|on-demand)/(?:[^/]+/)+[^/]+_|player/index\.html\?.*?\bprogramGuid=)([0-9A-Z]{16})""")[0]
        if not guid:
            return
        tp_path = "PR1GhC/media/guid/2702976343/" + guid
        uniqueUrls = set()
        retTab = []
        for asset_type in ("SD", "HD"):
            for f in "MPEG4":
                url = "https://link.theplatform.%s/s/%s?mbr=true&formats=%s&assetTypes=%s" % ("eu", tp_path, f, asset_type)
                sts, data = self.cm.getPage(url, post_data={"format": "SMIL"})
                if not sts:
                    continue
                if "GeoLocationBlocked" in data:
                    SetIPTVPlayerLastHostError(ph.getattr(data, "abstract"))
                tmp = ph.findall(data, "<video", ">")
                for item in tmp:
                    url = ph.getattr(item, "src")
                    if not self.cm.isValidUrl(url):
                        continue
                    if url not in uniqueUrls:
                        uniqueUrls.add(url)
                        retTab.append({"name": "%s - %s" % (f, asset_type), "url": url})
        return retTab

    def parserVIDCLOUDCO(self, baseUrl):
        printDBG("parserVIDCLOUDCO baseUrl[%r]" % baseUrl)
        baseUrl = strwithmeta(baseUrl)
        HTTP_HEADER = self.cm.getDefaultHeader(browser="firefox")
        referer = baseUrl.meta.get("Referer")
        if referer:
            HTTP_HEADER["Referer"] = referer
        COOKIE_FILE = GetCookieDir("vidcloud.co.cookie")
        urlParams = {"header": HTTP_HEADER, "use_cookie": True, "save_cookie": True, "load_cookie": False, "cookiefile": COOKIE_FILE}
        sts, data = self.cm.getPage(baseUrl, urlParams)
        if not sts:
            return False
        cUrl = self.cm.meta["url"]
        token = ph.getattr(ph.find(data, ("<meta", ">", "-token"), flags=ph.I | ph.START_E)[1], "content", flags=ph.I)
        urlParams["header"].update({"X-CSRF-TOKEN": token, "Referer": cUrl, "X-Requested-With": "XMLHttpRequest"})
        data = ph.find(data, ("function loadPlayer(", "{"), "}", flags=0)[1]
        url = self.cm.getFullUrl(ph.search(data, r"""url['"]?\s*:\s*['"]([^'^"]+?)['"]""")[0], cUrl)
        sts, data = self.cm.getPage(url, urlParams)
        if not sts:
            return False
        cUrl = self.cm.meta["url"]
        data = json_loads(data)
        printDBG(data["html"])
        return self._findLinks(data["html"], self.cm.getBaseUrl(baseUrl, True))

    def parserGOVIDME(self, baseUrl):
        printDBG("parserGOVIDME baseUrl[%r]" % baseUrl)
        baseUrl = strwithmeta(baseUrl)
        HTTP_HEADER = self.cm.getDefaultHeader(browser="chrome")
        referer = baseUrl.meta.get("Referer")
        if referer:
            HTTP_HEADER["Referer"] = referer
        urlParams = {"header": HTTP_HEADER}
        sts, data = self.cm.getPage(baseUrl, urlParams)
        if not sts:
            return False
        cUrl = self.cm.meta["url"]
        return self._findSourceLinks(data, cUrl, {"Referer": cUrl, "User-Agent": HTTP_HEADER["User-Agent"]})

    def parserHARPYTV(self, baseUrl):
        printDBG("parserHARPYTV baseUrl[%r]" % baseUrl)
        baseUrl = strwithmeta(baseUrl)
        HTTP_HEADER = self.cm.getDefaultHeader(browser="chrome")
        referer = baseUrl.meta.get("Referer")
        if referer:
            HTTP_HEADER["Referer"] = referer
        urlParams = {"header": HTTP_HEADER}
        sts, data = self.cm.getPage(baseUrl, urlParams)
        if not sts:
            return False
        cUrl = self.cm.meta["url"]
        return self._findSourceLinks(data, cUrl, {"Referer": cUrl, "User-Agent": HTTP_HEADER["User-Agent"]})

    def parserVIDEOSTREAMLETNET(self, baseUrl):
        printDBG("parserVIDEOSTREAMLETNET baseUrl[%r]" % baseUrl)
        baseUrl = strwithmeta(baseUrl)
        HTTP_HEADER = self.cm.getDefaultHeader(browser="chrome")
        referer = baseUrl.meta.get("Referer")
        if referer:
            HTTP_HEADER["Referer"] = referer
        urlParams = {"header": HTTP_HEADER}
        sts, data = self.cm.getPage(baseUrl, urlParams)
        if not sts:
            return False
        cUrl = self.cm.meta["url"]
        streamUrl = ph.search(data, r"""["']([^'^"]+?\.m3u8(?:\?[^"^']+?)?)["']""", flags=0)[0]
        streamUrl = strwithmeta(self.cm.getFullUrl(streamUrl, cUrl), {"Referer": cUrl, "User-Agent": HTTP_HEADER["User-Agent"]})
        return getDirectM3U8Playlist(streamUrl, checkContent=True, sortWithMaxBitrate=999999999)

    def parserVIUCLIPS(self, baseUrl):
        printDBG("parserVIUCLIPS baseUrl[%s]" % baseUrl)
        if "parserVIUCLIPS" in baseUrl:
            baseUrl = ph.search(baseUrl, r"""https?://.*parserVIUCLIPS\[([^"]+?)\]""")[0]
            printDBG("force parserVIUCLIPS baseUrl[%s]" % baseUrl)
        if "embed" not in baseUrl:
            video_id = ph.search(baseUrl, r"""https?://.*/player/.*/([a-zA-Z0-9]{13})\?""")[0]
            printDBG("parserVIUCLIPS video_id[%s]" % video_id)
            baseUrl = "{0}embed/{1}".format(urlparser.getDomain(baseUrl, False), video_id)
        sts, data = self.cm.getPage(baseUrl)
        if not sts:
            return False
        if "This video has been removed" in data:
            SetIPTVPlayerLastHostError("This video has been removed")
            return False
        vidTab = []
        hlsUrl = self.cm.ph.getSearchGroups(data, r"""["']([^'^"]+?\.m3u8(?:\?[^"^']+?)?)["']""", ignoreCase=True)[0]
        tmpUrl = urlparser.getDomain(hlsUrl)
        hlsUrl = hlsUrl.replace(tmpUrl + "//", tmpUrl + "/")
        if hlsUrl != "":
            if hlsUrl.startswith("//"):
                hlsUrl = "https:" + hlsUrl
            hlsUrl = strwithmeta(hlsUrl, {"Origin": "https://" + urlparser.getDomain(baseUrl), "Referer": baseUrl})
            vidTab.extend(getDirectM3U8Playlist(hlsUrl, checkExt=False, variantCheck=True, checkContent=True, sortWithMaxBitrate=99999999))
        return vidTab

    def parserONLYSTREAMTV(self, baseUrl):
        printDBG("parserONLYSTREAMTV baseUrl[%s]" % baseUrl)
        HTTP_HEADER = self.cm.getDefaultHeader(browser="chrome")
        referer = baseUrl.meta.get("Referer")
        if referer:
            HTTP_HEADER["Referer"] = referer
        urlParams = {"header": HTTP_HEADER}
        sts, data = self.cm.getPage(baseUrl, urlParams)
        if not sts:
            return False
        if "eval(function(p,a,c,k,e,d)" in data:
            printDBG("Host resolveUrl packed")
            scripts = re.findall(r"(eval\s?\(function\(p,a,c,k,e,d.*?)</script>", data, re.S)
            data = ""
            for packed in scripts:
                data2 = packed
                printDBG("Host pack: [%s]" % data2)
                try:
                    data += unpackJSPlayerParams(data2, TEAMCASTPL_decryptPlayerParams, 0, True, True)
                    printDBG("OK unpack: [%s]" % data)
                except Exception:
                    pass
        urltab = self._findLinks(data, meta={"Referer": baseUrl})
        if len(urltab) == 0:
            url = self.cm.ph.getSearchGroups(data, r"""["'](https?://[^'^"]+?\.mp4(?:\?[^"^']+?)?)["']""", ignoreCase=True)[0]
            if url != "":
                url = strwithmeta(url, {"Origin": "https://" + urlparser.getDomain(baseUrl), "Referer": baseUrl})
                urltab.append({"name": "mp4", "url": url})
            hlsUrl = self.cm.ph.getSearchGroups(data, r"""["'](https?://[^'^"]+?\.m3u8(?:\?[^"^']+?)?)["']""", ignoreCase=True)[0]
            if hlsUrl != "":
                hlsUrl = strwithmeta(hlsUrl, {"Origin": "https://" + urlparser.getDomain(baseUrl), "Referer": baseUrl})
                urltab.extend(getDirectM3U8Playlist(hlsUrl, checkExt=False, variantCheck=True, checkContent=True, sortWithMaxBitrate=99999999))
        return urltab

    def parserVIDCLOUD9(self, baseUrl):
        printDBG("parserVIDCLOUD9 baseUrl[%r]" % baseUrl)
        baseUrl = strwithmeta(baseUrl)
        HTTP_HEADER = self.cm.getDefaultHeader(browser="firefox")
        urlParams = {"header": HTTP_HEADER}
        urlParams["header"].update({"Referer": urlparser.getDomain(baseUrl, False), "X-Requested-With": "XMLHttpRequest"})
        _url = self.cm.ph.getSearchGroups(baseUrl, r"""https?://.+?/(.+?)\.php.+?""", ignoreCase=True)[0]
        sts, data = self.cm.getPage(baseUrl.replace(_url, "ajax"), urlParams)
        if not sts:
            return False
        data = json_loads(data)
        urltab = []
        for item in data["source"]:
            url = item.get("file", "")
            url = strwithmeta(url, {"Referer": baseUrl})
            label = item.get("label", "")
            if "m3u8" in url:
                urltab.extend(getDirectM3U8Playlist(url, checkContent=True, sortWithMaxBitrate=999999999))
            elif "mp4" in url:
                urltab.append({"name": "res: " + label, "url": url})
        for item in data["source_bk"]:
            url = item.get("file", "")
            url = strwithmeta(url, {"Referer": baseUrl})
            label = item.get("label", "")
            if "m3u8" in url:
                urltab.extend(getDirectM3U8Playlist(url, checkContent=True, sortWithMaxBitrate=999999999))
            elif "mp4" in url:
                urltab.append({"name": "res: " + label, "url": url})
        return urltab

    def parserNINJASTREAMTO(self, baseUrl):
        printDBG("parserNINJASTREAMTO baseUrl [%s]" % baseUrl)
        COOKIE_FILE = GetCookieDir("ninjastream.cookie")
        httpParams = {"header": {"User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36", "Accept": "*/*", "Accept-Encoding": "gzip", "Referer": baseUrl.meta.get("Referer", baseUrl)}, "use_cookie": True, "load_cookie": True, "save_cookie": True, "cookiefile": COOKIE_FILE}
        urlsTab = []
        sts, data = self.cm.getPage(baseUrl, httpParams)
        if sts:
            r = self.cm.ph.getSearchGroups(data, r'v-bind:[n|s]*stream="([^"]+?)"')[0].replace("&quot;", '"')
            if not r:
                r = self.cm.ph.getSearchGroups(data, r'v-bind:[n|s]*file="([^"]+?)"')[0].replace("&quot;", '"')
            printDBG("parserNINJASTREAMTO r [%s]" % r)
            httpParams["header"]["X-Requested-With"] = "XMLHttpRequest"
            httpParams["header"]["x-csrf-token"] = self.cm.ph.getSearchGroups(data, """<[^>]+?csrf-token[^>]+?content=['"]([^'^"]+?)['"]""")[0]
            httpParams["header"]["x-xsrf-token"] = self.cm.getCookieItem(COOKIE_FILE, "XSRF-TOKEN")
            if r:
                data = json_loads(r)
                sts, data = self.cm.getPage("https://ninjastream.to/api/video/get", httpParams, {"id": data.get("hashid")})
                if sts:
                    data = json_loads(data)
                    url = data["result"]["playlist"]
                    urlsTab.extend(getDirectM3U8Playlist(url, checkContent=True, sortWithMaxBitrate=999999999))
        return urlsTab

    def parserFASTSHARECZ(self, baseUrl):
        printDBG("parserFASTSHARECZ baseUrl[%s]" % baseUrl)
        HTTP_HEADER = self.cm.getDefaultHeader(browser="chrome")
        referer = baseUrl.meta.get("Referer")
        if referer:
            HTTP_HEADER["Referer"] = referer
        urlParams = {"header": HTTP_HEADER}
        sts, data = self.cm.getPage(baseUrl, urlParams)
        if not sts:
            return False
        url = self.cm.getFullUrl(self.cm.ph.getSearchGroups(data, r"""action=(\/free\/[^>]+?)>""")[0], baseUrl)
        urlParams["max_data_size"] = 0
        urlParams["no_redirection"] = True
        sts, data = self.cm.getPage(url, urlParams)
        if not sts:
            return False
        urltab = []
        url = self.cm.meta.get("location", "")
        if self.cm.isValidUrl(url):
            url = strwithmeta(url, {"Origin": "https://" + urlparser.getDomain(baseUrl), "Referer": baseUrl})
            urltab.append({"name": "mp4", "url": url})
        return urltab

    def parserRUMBLECOM(self, baseUrl):
        printDBG("parserRUMBLECOM baseUrl[%s]" % baseUrl)
        HTTP_HEADER = self.cm.getDefaultHeader(browser="chrome")
        referer = baseUrl.meta.get("Referer")
        if referer:
            HTTP_HEADER["Referer"] = referer
        urlParams = {"header": HTTP_HEADER}
        sts, data = self.cm.getPage(baseUrl, urlParams)
        if not sts:
            return False
        urltab = []
        data = self.cm.ph.getAllItemsBeetwenMarkers(data, '"url":', "}", withMarkers=True)
        for item in data:
            printDBG("parserRUMBLECOM item[%s]" % item)
            url = self.cm.ph.getSearchGroups(item, """['"]url['"]:['"]([^"^']+?)['"]""")[0].replace(r"\/", "/")
            if "mp4" not in url:
                continue
            name = self.cm.ph.getSearchGroups(item, r"""['"]w['"]:(\d+)""")[0] + "x" + self.cm.ph.getSearchGroups(item, r"""['"]h['"]:(\d+)""")[0]
            urltab.append({"name": name, "url": url})
        return urltab

    def parserSHOWSPORTXYZ(self, baseUrl):
        printDBG("parserSHOWSPORTXYZ baseUrl[%s]" % baseUrl)
        HTTP_HEADER = self.cm.getDefaultHeader(browser="chrome")
        referer = baseUrl.meta.get("Referer")
        if referer:
            HTTP_HEADER["Referer"] = referer
        urlParams = {"header": HTTP_HEADER}
        sts, data = self.cm.getPage(baseUrl, urlParams)
        if not sts:
            return []
        urltab = []
        url = self.cm.ph.getSearchGroups(data, r"""\swindow.atob\(['"]([^"^']+?)['"]""")[0]
        if url != "":
            url = urllib_unquote(base64.b64decode(url).replace("playoutengine.sinclairstoryline", "playoutengine-v2.sinclairstoryline"))
            url = strwithmeta(url, {"Referer": baseUrl})
            urltab.extend(getDirectM3U8Playlist(url, checkContent=True, sortWithMaxBitrate=999999999))
        return urltab

    def parserDADDYLIVE(self, baseUrl):
        printDBG("parserDADDYLIVE baseUrl[%s]" % baseUrl)
        HTTP_HEADER = self.cm.getDefaultHeader(browser="chrome")
        referer = baseUrl.meta.get("Referer")
        if referer:
            HTTP_HEADER["Referer"] = referer
        urlParams = {"header": HTTP_HEADER}
        sts, data = self.cm.getPage(baseUrl, urlParams)
        if not sts:
            return []
        cUrl = self.cm.meta["url"]
        data = self.cm.ph.getDataBeetwenNodes(data, ("<iframe", ">", "src"), ("</iframe", ">"))[1]
        url = self.cm.ph.getSearchGroups(data, """src=['"]([^"^']+?)['"]""")[0]
        HTTP_HEADER["Referer"] = cUrl
        urlParams = {"header": HTTP_HEADER}
        sts, data = self.cm.getPage(url, urlParams)
        if not sts:
            return []
        printDBG("parserDADDYLIVE data[%s]" % data)
        urltab = []
        data = self.cm.ph.getDataBeetwenMarkers(data, "Clappr.Player", ("</script", ">"), False)[1]
        url = self.cm.ph.getSearchGroups(data, r"""source:\s?['"]([^"^']+?)['"]""")[0]
        url = strwithmeta(url, {"Origin": urlparser.getDomain(baseUrl, False), "Referer": cUrl})
        if url != "":
            urltab.extend(getDirectM3U8Playlist(url, checkContent=True, sortWithMaxBitrate=999999999))
        return urltab

    def parserLIVEONSCORETV(self, baseUrl):
        printDBG("parserLIVEONSCORETV baseUrl[%s]" % baseUrl)
        HTTP_HEADER = self.cm.getDefaultHeader(browser="chrome")
        referer = baseUrl.meta.get("Referer")
        if referer:
            HTTP_HEADER["Referer"] = referer
        urlParams = {"header": HTTP_HEADER}
        sts, data = self.cm.getPage(baseUrl, urlParams)
        if not sts:
            return []
        cUrl = self.cm.meta["url"]
        data = self.cm.ph.getDataBeetwenMarkers(data, "var player", ("</script", ">"), False)[1]
        url = self.cm.ph.getSearchGroups(data, r"""url:\s*['"]([^"^']+?)['"]""")[0]
        UrlID = self.cm.ph.getSearchGroups(data, r"""var\svidgstream\s?=\s?['"]([^"^']+?)['"]""")[0]
        url = url + "?idgstream=" + urllib_quote(UrlID)
        HTTP_HEADER["Referer"] = cUrl
        urlParams = {"header": HTTP_HEADER}
        sts, data = self.cm.getPage(url, urlParams)
        if not sts:
            return []
        data = data.replace(r"\/", "/")
        urltab = []
        url = self.cm.ph.getSearchGroups(data, r"""["'](https?://[^'^"]+?\.mp4(?:\?[^"^']+?)?)["']""", ignoreCase=True)[0]
        if url != "":
            url = strwithmeta(url, {"Origin": "https://" + urlparser.getDomain(baseUrl), "Referer": baseUrl})
            urltab.append({"name": "mp4", "url": url})
        hlsUrl = self.cm.ph.getSearchGroups(data, r"""["'](https?://[^'^"]+?\.m3u8(?:\?[^"^']+?)?)["']""", ignoreCase=True)[0]
        if hlsUrl != "":
            hlsUrl = strwithmeta(hlsUrl, {"Origin": "https://" + urlparser.getDomain(baseUrl), "Referer": baseUrl})
            urltab.extend(getDirectM3U8Playlist(hlsUrl, checkExt=False, variantCheck=True, checkContent=True, sortWithMaxBitrate=99999999))
        return urltab

    def parserSPORTSONLINETO(self, baseUrl):
        printDBG("parserSPORTSONLINETO baseUrl[%r]" % baseUrl)
        HTTP_HEADER = self.cm.getDefaultHeader(browser="chrome")
        referer = baseUrl.meta.get("Referer")
        if referer:
            HTTP_HEADER["Referer"] = referer
        urlParams = {"header": HTTP_HEADER}
        sts, data = self.cm.getPage(baseUrl, urlParams)
        if not sts:
            return False
        cUrl = self.cm.meta["url"]
        _url = self.cm.ph.getSearchGroups(data, """<iframe[^>]+?src=['"](http[^"^']+?)['"]""", 1, True)[0]
        HTTP_HEADER["Referer"] = cUrl
        urlParams = {"header": HTTP_HEADER}
        sts, data = self.cm.getPage(_url, urlParams)
        if not sts:
            return False
        urltab = []
        if "eval(function(p,a,c,k,e,d)" in data:
            printDBG("Host resolveUrl packed")
            scripts = re.findall(r"(eval\s?\(function\(p,a,c,k,e,d.*?)</script>", data, re.S)
            for packed in scripts:
                data2 = packed
                printDBG("Host pack: [%s]" % data2)
                try:
                    data = unpackJSPlayerParams(data2, TEAMCASTPL_decryptPlayerParams, 0, True, True)
                    printDBG("OK unpack: [%s]" % data)
                except Exception:
                    pass
                url = self.cm.ph.getSearchGroups(data, r"""["'](https?://[^'^"]+?\.mp4(?:\?[^"^']+?)?)["']""", ignoreCase=True)[0]
                if url != "":
                    url = strwithmeta(url, {"Origin": "https://" + urlparser.getDomain(baseUrl), "Referer": _url})
                    urltab.append({"name": "mp4", "url": url})
                hlsUrl = self.cm.ph.getSearchGroups(data, r"""["'](https?://[^'^"]+?\.m3u8(?:\?[^"^']+?)?)["']""", ignoreCase=True)[0]
                if hlsUrl != "":
                    hlsUrl = strwithmeta(hlsUrl, {"Origin": "https://" + urlparser.getDomain(baseUrl), "Referer": _url})
                    urltab.extend(getDirectM3U8Playlist(hlsUrl, checkExt=False, variantCheck=True, checkContent=True, sortWithMaxBitrate=99999999))
        return urltab

    def parserHLSPLAYER(self, baseUrl):
        printDBG("parserHLSPLAYER baseUrl[%r]" % baseUrl)
        url = baseUrl.split("url=")[-1]
        url = urllib_unquote(url)
        urltab = []
        url = strwithmeta(url, {"Origin": "https://" + urlparser.getDomain(baseUrl), "Referer": baseUrl})
        urltab.extend(getDirectM3U8Playlist(url, checkExt=False, variantCheck=True, checkContent=True, sortWithMaxBitrate=99999999))
        return urltab

    def parserSTREAMLARE(self, baseUrl):
        printDBG("parserSTREAMLARE baseUrl[%s]" % baseUrl)
        urltab = []
        HTTP_HEADER = self.cm.getDefaultHeader(browser="chrome")
        urlParams = {"header": HTTP_HEADER}
        media_id = self.cm.ph.getSearchGroups(baseUrl + "/", "(?:e|v)[/-]([A-Za-z0-9]+)[^A-Za-z0-9]")[0]
        api_surl = "https://{0}/api/video/stream/get".format(urlparser.getDomain(baseUrl))
        post_data = {"id": media_id}
        sts, data = self.cm.getPage(api_surl, urlParams, post_data)
        if not sts:
            return False
        data = data.replace("\\/", "/")
        data = data.split("type")
        for item in data:
            videoUrl = self.cm.ph.getSearchGroups(item, r"""file['"]:\s?['"]([^"^']+?)['"]""")[0]
            videoUrl = strwithmeta(videoUrl, {"Referer": baseUrl})
            name = self.cm.ph.getSearchGroups(item, r"""label['"]:\s?['"]([^"^']+?)['"]""")[0]
            if videoUrl:
                params = {"name": name, "url": videoUrl}
                urltab.append(params)
        return urltab

    def parserFILEMOON(self, baseUrl):
        printDBG("parserFILEMOON baseUrl[%s]" % baseUrl)
        urltab = []
        HTTP_HEADER = self.cm.getDefaultHeader(browser="chrome")
        referer = baseUrl.meta.get("Referer")
        if referer:
            HTTP_HEADER["Referer"] = referer
        urlParams = {"header": HTTP_HEADER}
        sts, data = self.cm.getPage(baseUrl, urlParams)
        if not sts:
            return []
        if "file_code" not in data:
            url = self.cm.ph.getSearchGroups(data, """<iframe[^>]+?src=['"]([^"^']+?)['"]""", 1, True)[0]
            if url != "":
                sts, data = self.cm.getPage(url, urlParams)
                if not sts:
                    return []
        if "eval(function(p,a,c,k,e,d)" in data:
            printDBG("Host resolveUrl packed")
            scripts = re.findall(r"(eval\s?\(function\(p,a,c,k,e,d.*?)</script>", data, re.S)
            for packed in scripts:
                data2 = packed
                printDBG("Host pack: [%s]" % data2)
                try:
                    data = unpackJSPlayerParams(data2, TEAMCASTPL_decryptPlayerParams, 0, True, True)
                    printDBG("OK unpack: [%s]" % data)
                except Exception:
                    pass
        r = re.search(r"""b:\s*'([^']+)',\s*file_code:\s*'([^']+)',\s*hash:\s*'([^']+)""", data)
        if r:
            url = "https://{0}/dl".format(urlparser.getDomain(baseUrl))
            post_data = {"b": r.group(1), "file_code": r.group(2), "hash": r.group(3)}
            sts, data = self.cm.getPage(url, urlParams, post_data)
            if not sts:
                return []
            data = data.replace(self.cm.ph.getDataBeetwenMarkers(data, 'tracks":[', "]", False)[1], "")
            vfile = self.cm.ph.getSearchGroups(data, r"""file['"]:\s?['"]([^"^']+?)['"]""")[0]
            seed = self.cm.ph.getSearchGroups(data, r"""seed['"]:\s?['"]([^"^']+?)['"]""")[0]
            hlsUrl = tear_decode(vfile, seed)
        else:
            hlsUrl = self.cm.ph.getSearchGroups(data, r"""["'](https?://[^'^"]+?\.m3u8(?:\?[^"^']+?)?)["']""", ignoreCase=True)[0]
        if hlsUrl != "":
            hlsUrl = strwithmeta(hlsUrl, {"Origin": "https://" + urlparser.getDomain(baseUrl), "Referer": baseUrl})
            urltab.extend(getDirectM3U8Playlist(hlsUrl, checkExt=False, variantCheck=True, checkContent=True, sortWithMaxBitrate=99999999))
        return urltab

    def parserODYSEECOM(self, baseUrl):
        printDBG("parserODYSEECOM baseUrl[%s]" % baseUrl)
        HTTP_HEADER = self.cm.getDefaultHeader(browser="chrome")
        referer = baseUrl.meta.get("Referer")
        if referer:
            HTTP_HEADER["Referer"] = referer
        urlParams = {"header": HTTP_HEADER}
        sts, data = self.cm.getPage(baseUrl, urlParams)
        if not sts:
            return []
        urltab = []
        url = self.cm.ph.getSearchGroups(data, r"""contentUrl['"]:\s?['"]([^"^']+?)['"]""")[0]
        url = strwithmeta(url, {"Origin": urlparser.getDomain(baseUrl, False), "Referer": baseUrl})
        if url != "":
            urltab.append({"name": "mp4", "url": url})
        return urltab

    def parserVIDMOLYME(self, baseUrl):
        printDBG("parserVIDMOLYME baseUrl[%r]" % baseUrl)
        HTTP_HEADER = self.cm.getDefaultHeader(browser="chrome")
        baseUrl = strwithmeta(baseUrl)
        if "embed" not in baseUrl:
            video_id = self.cm.ph.getSearchGroups(baseUrl + "/", "/([A-Za-z0-9]{12})[/.]")[0]
            printDBG("parserVIDMOLYME video_id[%s]" % video_id)
            baseUrl = urlparser.getDomain(baseUrl, False) + "/embed-{0}.html".format(video_id)
        sts, data = self.cm.getPage(baseUrl, {"header": HTTP_HEADER})
        if not sts:
            return False
        cUrl = self.cm.meta["url"]
        if "<title>Please wait</title>" in data:
            sts, data = self.cm.getPage(baseUrl.replace(".me/", ".to/"), {"header": HTTP_HEADER})
        urltab = []
        url = self.cm.ph.getSearchGroups(data, """sources[^'^"]*?['"]([^'^"]+?)['"]""")[0]
        if url == "":
            url = self.cm.ph.getSearchGroups(data, """<iframe[^>]*?src=["'](http[^"^']+?)["']""", 1, True)[0]
            sts, data = self.cm.getPage(url, {"header": HTTP_HEADER})
            if not sts:
                return False
            cUrl = self.cm.meta["url"]
            url = self.cm.ph.getSearchGroups(data, """sources[^'^"]*?['"]([^'^"]+?)['"]""")[0]
        url = strwithmeta(url, {"Origin": urlparser.getDomain(cUrl, False), "Referer": cUrl})
        if url != "":
            urltab.extend(getDirectM3U8Playlist(url, checkContent=True, sortWithMaxBitrate=999999999))
        return urltab

    def parserVIDGUARDTO(self, baseUrl):
        printDBG("parserVIDGUARDTO baseUrl[%s]" % baseUrl)

        def sig_decode(url):
            sig = url.split("sig=")[1].split("&")[0]
            t = ""
            for v in unhexlify(sig):
                t += chr((v if isinstance(v, int) else ord(v)) ^ 2)
            t = list(base64.b64decode(t + "==")[:-5][::-1])
            for i in range(0, len(t) - 1, 2):
                t[i + 1], t[i] = t[i], t[i + 1]
            t = "".join(chr((i if isinstance(i, int) else ord(i))) for i in t)
            url = url.replace(sig, "".join(t)[:-5])
            return url

        HTTP_HEADER = self.cm.getDefaultHeader(browser="chrome")
        referer = baseUrl.meta.get("Referer")
        if referer:
            HTTP_HEADER["Referer"] = referer
        urlParams = {"header": HTTP_HEADER}
        baseUrl = baseUrl.replace("/v/", "/e/")
        sts, data = self.cm.getPage(baseUrl, urlParams)
        if not sts:
            return []
        cUrl = self.cm.meta["url"]
        urltab = []
        r = re.search(r'eval\("window\.ADBLOCKER\s*=\s*false;\\n(.+?);"\);</script', data)
        if r:
            r = r.group(1).replace("\\u002b", "+")
            r = r.replace("\\u0027", "'")
            r = r.replace("\\u0022", '"')
            r = r.replace("\\/", "/")
            r = r.replace("\\\\", "\\")
            r = r.replace('\\"', '"')
            aa_decoded = aadecode.decode(r, alt=True)
            stream_url = json_loads(aa_decoded[11:]).get("stream")
            if stream_url:
                if isinstance(stream_url, list):
                    sources = [(x.get("Label"), x.get("URL")) for x in stream_url]
                    for item in sources:
                        url = item[1]
                        if not url.startswith("https://"):
                            url = re.sub(":/*", "://", url)
                        url = strwithmeta(sig_decode(url), {"Origin": urlparser.getDomain(baseUrl, False), "Referer": cUrl})
                        urltab.append({"name": item[0], "url": url})
                else:
                    url = strwithmeta(sig_decode(stream_url), {"Origin": urlparser.getDomain(baseUrl, False), "Referer": cUrl})
                    urltab.append({"name": "mp4", "url": url})
        return urltab

    def parserVOODCCOM(self, baseUrl):
        printDBG("parserVOODCCOM baseUrl[%s]" % baseUrl)
        HTTP_HEADER = self.cm.getDefaultHeader(browser="chrome")
        referer = baseUrl.meta.get("Referer")
        if referer:
            HTTP_HEADER["Referer"] = referer
        urlParams = {"header": HTTP_HEADER}
        sts, data = self.cm.getPage(baseUrl, urlParams)
        if not sts:
            return []
        urltab = []
        script = "https:" + re.findall(r'" src="(.+?)"', data)[0]
        split = script.split("/")
        embed_url = "https://voodc.com/player/d/%s/%s" % (split[-1], split[-2])
        sts, data = self.cm.getPage(embed_url, urlParams)
        if not sts:
            return []
        m3u8 = re.findall(r'"file": \'(.+?)\'', data)[0]
        if "m3u8" in data:
            urltab.extend(getDirectM3U8Playlist(m3u8, checkExt=False, variantCheck=True, checkContent=True, sortWithMaxBitrate=99999999))
        return urltab

    def parserVOESX(self, baseUrl):
        def voe_decode(ct):
            txt = "".join(chr((ord(i) - 52) % 26 + 65) if 65 <= ord(i) <= 90 else chr((ord(i) - 84) % 26 + 97) if 97 <= ord(i) <= 122 else i for i in ct)
            lut = [r"#&", r"%?", r"\*~", r"~@", r"\^\^", r"!!", r"@$"]
            for pattern in lut:
                txt = re.sub(pattern, "_", txt)
            txt = "".join(txt.split("_"))

            def fix_b64_padding(s):
                return s + "=" * (-len(s) % 4)

            try:
                step1 = base64.b64decode(fix_b64_padding(txt)).decode()
                step2 = "".join(chr(ord(c) - 3) for c in step1)
                final = base64.b64decode(fix_b64_padding(step2[::-1])).decode()
                return json_loads(final)
            except Exception as e:
                printDBG(e)
                return ""

        printDBG("parserVOESX baseUrl[%r]" % baseUrl)
        sts, data = self.cm.getPage(baseUrl)
        if not sts:
            return False
        if "const currentUrl" in data:
            url = ph.search(data, r"""window.location.href\s*=\s*['"]([^"^']+?)['"]""")[0]
            sts, data = self.cm.getPage(url)
            if not sts:
                return False
        r = re.search(r"""['"]?hls['"]?\s*?:\s*?['"]([^'^"]+?)['"]""", data)
        if r:
            hlsUrl = ensure_str(base64.b64decode(r.group(1)))
            if hlsUrl.startswith("//"):
                hlsUrl = "https:" + hlsUrl
            if self.cm.isValidUrl(hlsUrl):
                params = {"iptv_proto": "m3u8", "Referer": baseUrl, "Origin": urlparser.getDomain(baseUrl, False)}
                hlsUrl = urlparser.decorateUrl(hlsUrl, params)
                return getDirectM3U8Playlist(hlsUrl, checkExt=False, checkContent=True, sortWithMaxBitrate=999999999)
        else:
            r = re.search(r'\w+="([^"]+)";function', data)
            if not r:
                r = re.search(r"""application/json">[^>]"([^"]+)""", data)
            urltab = []
            if r:
                r = voe_decode(ensure_str(r.group(1)))
                if r:
                    subtitles = [{"title": "", "lang": x.get("label"), "url": "https://{0}{1}".format(baseUrl.split("/")[2], x.get("file"))} for x in r.get("captions") if x.get("kind") == "captions"]
                    key_list = ["source", "file", "direct_access_url"]
                    for key in key_list:
                        if key in r:
                            url = r[key]
                            if ".m3u8" in url:
                                url = urlparser.decorateUrl(url, {"iptv_proto": "m3u8", "Referer": baseUrl, "Origin": urlparser.getDomain(baseUrl, False), "external_sub_tracks": subtitles})
                                urltab.extend(getDirectM3U8Playlist(url, checkExt=False, checkContent=True, sortWithMaxBitrate=999999999))
                            else:
                                if subtitles:
                                    url = urlparser.decorateUrl(url, {"external_sub_tracks": subtitles})
                                urltab.append({"name": "MP4", "url": url})
            return urltab

    def parserSTREAMSILKCOM(self, baseUrl):
        printDBG("parserSTREAMSILKCOM baseUrl[%s]" % baseUrl)
        HTTP_HEADER = self.cm.getDefaultHeader(browser="chrome")
        referer = baseUrl.meta.get("Referer")
        if referer:
            HTTP_HEADER["Referer"] = referer
        urlParams = {"header": HTTP_HEADER}
        sts, data = self.cm.getPage(baseUrl, urlParams)
        if not sts:
            return []
        if "function(h,u,n,t,e,r)" in data:
            ff = re.findall(r'function\(h,u,n,t,e,r\).*?}\((".+?)\)\)', data, re.DOTALL)[0]
            ff = ff.replace('"', "")
            h, u, n, t, e, r = ff.split(",")
            data = dehunt(h, int(u), n, int(t), int(e), int(r))
        urltab = []
        url = self.cm.ph.getSearchGroups(data, r"""urlPlay\s*=\s*"\s*([^"^\s]+)""")[0]
        url = strwithmeta(url, {"Origin": urlparser.getDomain(baseUrl, False), "Referer": baseUrl})
        if url != "":
            if "m3u8" in url:
                urltab.extend(getDirectM3U8Playlist(url, checkExt=False, variantCheck=True, checkContent=True, sortWithMaxBitrate=99999999))
            else:
                urltab.append({"name": "mp4", "url": url})
        return urltab

    def parserVEEV(self, baseUrl):  # check 150625
        printDBG("parserVEEV baseUrl[%s]" % baseUrl)
        HTTP_HEADER = self.cm.getDefaultHeader(browser="chrome")
        HTTP_HEADER.update({"Referer": baseUrl, "Origin": urlparser.getDomain(baseUrl, False), "Accept-Language": "en-US,en;q=0.5"})
        urlParams = {"header": HTTP_HEADER}

        def veev_decode(etext):
            result = []
            lut = {}
            n = 256
            c = etext[0]
            result.append(c)
            for char in etext[1:]:
                code = ord(char)
                nc = char if code < 256 else lut.get(code, c + c[0])
                result.append(nc)
                lut[n] = c + nc[0]
                n += 1
                c = nc
            return "".join(result)

        def js_int(x):
            return int(x) if x.isdigit() else 0

        def build_array(encoded_string):
            d = []
            c = list(encoded_string)
            count = js_int(c.pop(0))
            while count:
                current_array = []
                for x in range(count):
                    current_array.insert(0, js_int(c.pop(0)))
                d.append(current_array)
                count = js_int(c.pop(0))
            return d

        def decode_url(etext, tarray):
            ds = etext
            for t in tarray:
                if t == 1:
                    ds = ds[::-1]
                ds = unhexlify(ds).decode("utf8")
                ds = ds.replace("dXRmOA==", "")
            return ds

        urltab = []
        sub_tracks = []
        sts, data = self.cm.getPage(baseUrl, urlParams)
        if not sts:
            return []
        url = self.cm.meta.get("url", "")
        if url != "":
            baseUrl = url
        # New verison:
        # items = re.findall(r"""[\.\s'](?:fc|_vvto\[[^\]]*)(?:['\]]+)?\s*[:=]\s*['"]([^'"]+)""", data)
        # needs to be tested !
        items = re.findall(r"""[\.\s'](?:fc|_vvto\[[^\]]*)(?:['\]]*)?\s*[:=]\s*['"]([^'"]+)""", data)
        if items:
            for f in items[::-1]:
                ch = veev_decode(ensure_binary(f).decode("utf8"))
                if ch != f:
                    params = {"op": "player_api", "cmd": "gi", "file_code": baseUrl.split("/")[-1], "ch": ch, "ie": 1}
                    durl = self.cm.getFullUrl("/dl", baseUrl) + "?" + urllib_urlencode(params)
                    sts, jresp = self.cm.getPage(durl, urlParams)
                    if not sts:
                        return []
                    jresp = json_loads(jresp).get("file")
                    if jresp and jresp.get("file_status") == "OK":
                        sub_tracks = [{"title": sub.get("label"), "url": sub.get("src"), "lang": sub.get("language")} for sub in jresp.get("captions_list", [])]
                        url = decode_url(veev_decode(ensure_binary(jresp.get("dv")[0].get("s")).decode("utf8")), build_array(ch)[0])
                        if url:
                            url = strwithmeta(url, HTTP_HEADER)
                            urltab.append({"name": "MP4", "url": urlparser.decorateUrl(url, {"external_sub_tracks": sub_tracks})})
        return urltab

    def parserDOOD(self, baseUrl):  # update 240925
        urlsTab = []
        sub_tracks = []
        printDBG("parserDOOD baseUrl [%s]" % baseUrl)
        HTTP_HEADER = self.cm.getDefaultHeader(browser="chrome")
        urlParams = {"header": HTTP_HEADER}
        urls = ["all3do.com", "d0000d.com", "d000d.com", "d0o0d.com", "d-s.io", "do0od.com", "dooodster.com", "doodstream.com", "doply.net", "dooood.com", "do7go.com", "ds2play.com", "ds2video.com", "dood.cx", "dood.la", "dood.li", "dood.pm", "dood.re", "dood.sh", "dood.so", "dood.stream", "dood.to", "dood.watch", "dood.work", "dood.wf", "dood.ws", "dood.yt", "doods.pro", "doodcdn.io", "vide0.net", "vidply.com", "vvide0.com"]
        for url in urls:
            if url in baseUrl:
                baseUrl = baseUrl.replace(url, "dsvplay.com")
        host = "https://%s" % urlparser.getDomain(baseUrl, True)
        if "/d/" in baseUrl:
            sts, data = self.cm.getPage(baseUrl, urlParams)
            if not sts:
                return []
            url = self.cm.ph.getSearchGroups(data, 'iframe src="([^"]+)')[0]
            baseUrl = host + url
        sts, data = self.cm.getPage(baseUrl, urlParams)
        if not sts:
            return []
        sub = re.findall(r"""dsplayer\.addRemoteTextTrack\({src:'([^']+)',\s*label:'([^']*)',kind:'captions'""", data)
        if sub:
            sub_tracks = [{"title": "", "url": "https:" + src if src.startswith("//") else src, "lang": label} for src, label in sub if len(label) > 1]
        match = re.search(r"""dsplayer\.hotkeys[^']+'([^']+).+?function\s*makePlay.+?return[^?]+([^"]+)""", data, re.DOTALL)
        if match:
            token = match.group(2)
            sts, data = self.cm.getPage("%s%s" % (host, match.group(1)), urlParams)
            if not sts:
                return []
            url = data.strip() if "cloudflarestorage." in data else random_seed(10, data) + token + str(int(time.time() * 1000))
            url = urlparser.decorateUrl(url, {"external_sub_tracks": sub_tracks, "User-Agent": urlParams["header"]["User-Agent"], "Referer": baseUrl})
            urlsTab.append({"name": "mp4", "url": url})
        return urlsTab

    def parserSTREAMTAPE(self, baseUrl):  # check 150625
        printDBG("parserSTREAMTAPE baseUrl[%s]" % baseUrl)
        urltabs = []
        subTracks = []
        COOKIE_FILE = GetCookieDir("streamtape.cookie")
        httpParams = {"header": {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:139.0) Gecko/20100101 Firefox/139.0", "Accept": "*/*", "Accept-Encoding": "gzip", "Referer": baseUrl.meta.get("Referer", baseUrl)}, "use_cookie": True, "load_cookie": True, "save_cookie": True, "cookiefile": COOKIE_FILE}
        sts, data = self.cm.getPage(baseUrl, httpParams)
        code = self.cm.meta["status_code"]
        if sts and code != 404:
            subTracksData = self.cm.ph.getAllItemsBeetwenMarkers(data, "<track ", ">", False, False)
            for track in subTracksData:
                if 'kind="captions"' not in track:
                    continue
                subUrl = self.cm.ph.getSearchGroups(track, 'src="([^"]+?)"')[0]
                if subUrl.startswith("/"):
                    subUrl = urlparser.getDomain(baseUrl, False) + subUrl
                if subUrl.startswith("http"):
                    subLang = self.cm.ph.getSearchGroups(track, 'srclang="([^"]+?)"')[0]
                    subLabel = self.cm.ph.getSearchGroups(track, 'label="([^"]+?)"')[0]
                    subTracks.append({"title": subLabel + "_" + subLang, "url": subUrl, "lang": subLang, "format": "srt"})
            t = self.cm.ph.getSearchGroups(data, """innerHTML = ([^;]+?);""")[0] + ";"
            printDBG("parserSTREAMTAPE t[%s]" % t)
            t = t.replace(".substring(", "[", 1).replace(").substring(", ":][").replace(");", ":]") + "[1:]"
            t = eval(t)
            if t.startswith("/"):
                t = "https:/" + t
            if self.cm.isValidUrl(t):
                cookieHeader = self.cm.getCookieHeader(COOKIE_FILE, [], False)
                params = {"Cookie": cookieHeader, "Referer": httpParams["header"]["Referer"], "User-Agent": httpParams["header"]["User-Agent"]}
                params["external_sub_tracks"] = subTracks
                t = urlparser.decorateUrl(t, params)
                params = {"name": "link", "url": t}
                urltabs.append(params)
        return urltabs

    def parserSST(self, url):  # check 150625
        printDBG("parserSST baseUrl[%s]" % url)
        sts, data = self.cm.getPage(url)
        if not sts:
            return []
        urltab = []
        url = re.search('file:"([^"]+)', data)
        if url:
            url = url.group(1)
            if "[" in url:
                urls = re.findall(r"\[(\d+p)\](https?://[^\s,]+)", url)
                urltab.extend({"name": quality, "url": url} for quality, url in urls)
            else:
                urltab.append({"name": "360p", "url": url})
        return urltab

    def parserSBS(self, baseUrl):  # update 150825
        printDBG("parserSBS baseUrl[%s]" % baseUrl)
        HTTP_HEADER = self.cm.getDefaultHeader(browser="chrome")
        referer = baseUrl.meta.get("Referer")
        HTTP_HEADER["Referer"] = "https://%s/" % baseUrl.split("/")[2]
        urlParams = {"header": HTTP_HEADER}
        if "#" in baseUrl and referer:
            host = referer.split("/")[2]
            url = urlparser.getDomain(baseUrl, False)
            baseUrl = "%sapi/v1/video?id=%s&w=1904&h=969&r=%s" % (url, baseUrl.split("#")[1], host)
        sts, data = self.cm.getPage(baseUrl, urlParams)
        if not sts:
            return []
        data = unhexlify(data[:-1])
        decrypter = pyaes.Decrypter(pyaes.AESModeOfOperationCBC(b"\x6b\x69\x65\x6d\x74\x69\x65\x6e\x6d\x75\x61\x39\x31\x31\x63\x61", b"\x31\x32\x33\x34\x35\x36\x37\x38\x39\x30\x6f\x69\x75\x79\x74\x72"))
        data = decrypter.feed(data)
        data += decrypter.feed()
        data = data.decode("utf-8")
        data = json_loads(data)
        hls = data.get("source")
        urltab = []
        if hls:
            hls = urlparser.decorateUrl(hls, {"iptv_proto": "m3u8", "User-Agent": HTTP_HEADER["User-Agent"], "Referer": "https://%s/" % url, "Origin": "https://%s" % url})
            urltab.extend(getDirectM3U8Playlist(hls))
        return urltab

    def parserVINOVO(self, baseUrl):  # fix 15.06.25
        printDBG("parserVINOVO baseUrl[%s]" % baseUrl)
        COOKIE_FILE = self.COOKIE_PATH + "vinovo.cookie"
        HTTP_HEADER = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:139.0) Gecko/20100101 Firefox/139.0"}
        sts, data = self.cm.getPage(baseUrl, {"header": HTTP_HEADER, "use_cookie": True, "save_cookie": True, "load_cookie": False, "cookiefile": COOKIE_FILE})
        if not sts:
            return []
        token = re.search(r'name="token"\s*content="([^"]+)', data)
        video_data = re.search(r'data-base="([^"]+)', data)
        filecode = re.search(r'file_code"\s*(?:content="([^"]*)"|\s*="([^"]*)")>', data)
        if token and video_data and filecode:
            rurl = urljoin(baseUrl, "/")
            recaptcha = girc(data, rurl)
            HTTP_HEADER.update({"Origin": rurl[:-1], "Referer": baseUrl, "X-Requested-With": "XMLHttpRequest"})
            post_data = {"token": token.group(1), "recaptcha": recaptcha}
            api_url = "https://vinovo.to/api/file/url/{0}".format(filecode.group(1))
            sts, data = self.cm.getPage(api_url, {"header": HTTP_HEADER, "use_cookie": True, "save_cookie": False, "load_cookie": True, "cookiefile": COOKIE_FILE}, post_data)
            if not sts:
                return []
            resp_json = json_loads(data)
            if resp_json.get("status") == "ok":
                HTTP_HEADER.pop("X-Requested-With")
                vid_src = "{0}/stream/{1}".format(video_data.group(1), resp_json.get("token"))
                return [{"name": "MP4", "url": urlparser.decorateUrl(vid_src, HTTP_HEADER)}]
        return []

    def parserSTREAMEMBED(self, baseUrl):  # fix 191025
        urltab = []
        printDBG("parserSTREAMEMBED baseUrl[%s]" % baseUrl)
        headers = self.cm.getDefaultHeader(browser="chrome")
        host = urlparser.getDomain(baseUrl, False)
        COOKIE_FILE = self.COOKIE_PATH + "streamembed.cookie"
        sts, data = self.cm.getPage(baseUrl, {"header": headers, "use_cookie": True, "save_cookie": True, "load_cookie": False, "cookiefile": COOKIE_FILE})
        if not sts:
            return []
        data = re.search(r"var\s*video\s*=\s*(.*?);\s", data)
        if data:
            headers.update({"Referer": baseUrl})
            data = json_loads(data.group(1))
            url = "{}m3u8/{}/{}/master.txt?s=1&id={}&cache=1".format(host, data.get("uid"), data.get("md5"), data.get("id"))
            headers["Referer"] = baseUrl
            headers["Accept"] = "*/*"
            url = urlparser.decorateUrl(url, {"header": headers, "use_cookie": True, "save_cookie": False, "load_cookie": True, "cookiefile": COOKIE_FILE})
            urltab.extend(getDirectM3U8Playlist(url))
        return urltab

    def parserHEXLOAD(self, baseUrl):  # add 160625
        printDBG("parserHEXLOAD baseUrl[%s]" % baseUrl)
        HTTP_HEADER = self.cm.getDefaultHeader(browser="chrome")
        urltab = []
        postdata = {"op": "download3", "id": urlparse(baseUrl).path.strip("/"), "ajax": "1", "method_free": "1", "dataType": "json"}
        sts, data = self.cm.getPage("https://hexload.com/download", HTTP_HEADER, postdata)
        if not sts:
            return []
        data = json_loads(data)
        url = data.get("result", {}).get("url")
        if url:
            urltab.append({"name": "mp4", "url": url})
        return urltab

    def parserVIDEA(self, baseUrl):  # add 180625
        printDBG("parserVIDEA baseUrl[%s]" % baseUrl)
        HTTP_HEADER = self.cm.getDefaultHeader(browser="chrome")
        STATIC_SECRET = "xHb0ZvME5q8CBcoQi6AngerDu3FGO9fkUlwPmLVY_RTzj2hJIS4NasXWKy1td7p"
        sts, data = self.cm.getPage(baseUrl, HTTP_HEADER)
        if not sts:
            return []
        url = baseUrl if "/player" in baseUrl else urljoin(baseUrl, re.search(r'<iframe.*?src="(/player\?[^"]+)"', data).group(1))
        sts, nonce = self.cm.getPage(url, HTTP_HEADER)
        if not sts:
            return []
        nonce = re.search(r'_xt\s*=\s*"([^"]+)"', nonce).group(1)
        l, s = nonce[:32], nonce[32:]
        result = "".join(s[i - (STATIC_SECRET.index(l[i]) - 31)] for i in range(32))
        query = parse_qs(urlparse(url).query)
        _s = random_seed(8)
        _t = result[:16]
        _param = "f=%s" % query["f"][0] if "f" in query else "v=%s" % query["v"][0]
        hurl = "https://%s/player/xml?platform=desktop&%s&_s=%s&_t=%s" % (urlparser.getDomain(baseUrl), _param, _s, _t)
        sts, videaXml = self.cm.getPage(hurl, {"header": HTTP_HEADER, "collect_all_headers": True})
        if not sts:
            return []
        if not videaXml.startswith("<?xml"):
            key = result[16:] + _s + self.cm.meta.get("x-videa-xs", "")
            videaXml = rc4(videaXml, key)
        urltab = []
        source = re.findall(r'video_source\s*name="([^"]+).*?exp="([^"]+)">([^<]+)', videaXml)
        if source:
            for label, exp, url in source:
                url = "https:" + url if url.startswith("//") else url
                url = "%s?md5=%s&expires=%s" % (url, re.search(r"<hash_value_%s>([^<]+)<" % label, videaXml).group(1), exp)
                urltab.append({"name": label, "url": url})
            urltab.reverse()
        return urltab

    def parserSTREAMUP(self, baseUrl):  # update 261125
        printDBG("parserSTREAMUP baseUrl[%s]" % baseUrl)
        HTTP_HEADER = self.cm.getDefaultHeader(browser="chrome")
        urltab = []
        subTracks = []
        host = urlparser.getDomain(baseUrl, False)
        sts, data = self.cm.getPage("%sajax/stream?filecode=%s" % (host, urlparse(baseUrl).path.strip("/")), HTTP_HEADER)
        if not sts:
            return []
        data = json_loads(data)
        url = data.get("streaming_url")
        subTracks = [{"title": "", "url": sub.get("file_path"), "lang": sub.get("language")} for sub in data.get("subtitles", []) if sub.get("file_path") and sub.get("language")]
        if url:
            url = url.replace("\r", "").replace("\n", "")
            url = urlparser.decorateUrl(url, {"User-Agent": HTTP_HEADER["User-Agent"], "Referer": host, "Origin": host[:-1], "external_sub_tracks": subTracks})
            if ".m3u8" in url:
                urltab.extend(getDirectM3U8Playlist(url))
            else:
                urltab.append({"name": "MP4", "url": url})
        return urltab

    def parserSHAREVIDEO(self, url):  # add 160925
        printDBG("parserSHAREVIDEO baseUrl[%s]" % url)
        HTTP_HEADER = self.cm.getDefaultHeader(browser="chrome")
        host = urlparser.getDomain(url, False)
        sts, data = self.cm.getPage("%sapi/v1/videos/%s" % (host, url.split("/")[-1]), HTTP_HEADER)
        if not sts:
            return []
        urltab = []
        url = self.cm.ph.getSearchGroups(data, 'playlistUrl":"([^"]+)')[0]
        if url:
            url = urlparser.decorateUrl(url, {"User-Agent": HTTP_HEADER["User-Agent"], "Referer": host, "Origin": host[:-1]})
            urltab.extend(getDirectM3U8Playlist(url))
        return urltab

    def parserf16px(self, url):  # fix 221125
        def ft(e):
            t = e.replace("-", "+").replace("_", "/")
            r = 0 if len(t) % 4 == 0 else 4 - len(t) % 4
            n = t + "=" * r
            return base64.b64decode(n)

        def xn(e):
            return b"".join(list(map(ft, e)))

        printDBG("parserf16px baseUrl[%s]" % url)
        host = urlparser.getDomain(url, False)
        urltab = []
        HTTP_HEADER = self.cm.getDefaultHeader(browser="chrome")
        sts, data = self.cm.getPage(url.replace("/e/", "/api/videos/") + "/embed/playback", HTTP_HEADER)
        if not sts:
            return []
        html = json_loads(data)
        pd = html.get("playback")
        if pd:
            iv = ft(pd.get("iv"))
            key = xn(pd.get("key_parts"))
            pl = ft(pd.get("payload"))
            cipher = python_aesgcm.new(key)
            ct = cipher.open(iv, pl)
            html = json_loads(ct.decode("latin-1"))
        sources = html.get("sources")
        if sources:
            for x in sources:
                url = urlparser.decorateUrl(x.get("url"), {"User-Agent": HTTP_HEADER["User-Agent"], "Referer": host, "Origin": host[:-1]})
                if ".m3u8" in url:
                    urltab.extend(getDirectM3U8Playlist(url))
                else:
                    urltab.append({"name": x.get("label", ""), "url": url})
        return urltab

    def parserCOUDMAILRU(self, baseUrl):  # Fix 221125
        printDBG("parserCOUDMAILRU baseUrl[%s]" % baseUrl)
        HTTP_HEADER = self.cm.getDefaultHeader(browser="chrome")
        sts, data = self.cm.getPage(baseUrl, {"header": HTTP_HEADER})
        if not sts:
            return []
        urltab = []
        host = urlparser.getDomain(baseUrl, False)
        m = re.search(r'"weblink"\s*:\s*"([^"]+?)"', data)
        r = re.search(r'1","url":"([^"]+)"[^>],"view', data)
        if r and m:
            b = base64.b64encode(m.group(1).encode("utf-8")).decode("utf-8")
            url = "%s/0p/%s.m3u8?double_encode=1" % (r.group(1), b)
            url = urlparser.decorateUrl(url, {"User-Agent": HTTP_HEADER["User-Agent"], "Referer": host, "Origin": host[:-1]})
            urltab.extend(getDirectM3U8Playlist(url))
        return urltab

    def parserJWPLAYER(self, baseUrl):
        def jw_hidden(html, url):
            domain = urlparser.getDomain(url, False)[:-1]
            mediaid = url.rstrip(".html").split("/")[-1].split("-")[-1]
            forms = {}
            for form in re.finditer(r"<form[^>]*>(.*?)</form>", html, re.DOTALL | re.I):
                purl = re.search(r'action\s*=\s*[\'"]([^\'"]+)', form.group(0))
                for field in re.finditer(r'type=[\'"]?(hidden|submit)[\'"]?[^>]*>', form.group(1)):
                    name = re.search(r'name\s*=\s*[\'"]([^\'"]+)', field.group(0))
                    value = re.search(r'value\s*=\s*[\'"]([^\'"]*)', field.group(0))
                    if name and value:
                        name = name.group(1)
                        value = value.group(1)
                        if name == "file_code" and value == "":
                            value = mediaid
                        forms[name] = value
                if purl:
                    purl = purl.group(1)
                    if purl.startswith("/"):
                        purl = domain + purl
                    if purl and forms:
                        GetIPTVSleep().Sleep(6)
                        sts, data = self.cm.getPage(purl, urlParams, forms)
                        if sts:
                            return data
            return ""

        printDBG("parserJWPLAYER baseUrl[%s]" % baseUrl)
        urltab = []
        COOKIE_FILE = GetCookieDir("%s.cookie" % urlparser.getDomain(baseUrl))
        HTTP_HEADER = self.cm.getDefaultHeader(browser="chrome")
        HTTP_HEADER["Referer"] = baseUrl.meta.get("Referer", urlparser.getDomain(baseUrl, False))
        urlParams = {"header": HTTP_HEADER, "use_cookie": True, "load_cookie": True, "save_cookie": True, "cookiefile": COOKIE_FILE}
        if "mxdrop" in baseUrl or "mixdro" in baseUrl or "mixdrp" in baseUrl:
            baseUrl = baseUrl.replace(".co/", ".my/").replace(".club/", ".my/")
            baseUrl = "/".join(baseUrl.split("/")[:5]).replace("/f/", "/e/") if "/f/" in baseUrl else baseUrl
        if "hglink.to" in baseUrl:
            baseUrl = baseUrl.replace("hglink.to", "uasopt.com")
        if "cybervynx.com" in baseUrl:
            baseUrl = baseUrl.replace("cybervynx.com", "guxhag.com")
        if "streamwish.to" in baseUrl:
            baseUrl = baseUrl.replace("streamwish.to", "guxhag.com")
        sts, data = self.cm.getPage(baseUrl, urlParams)
        if not sts:
            return []
        if "p,a,c,k,e" not in data and "mp4" not in data and "m3u8" not in data:
            src = re.search(r'(?:data-embed|iframe\s+src)="([^"]+)"', data)
            if src:
                sts, data = self.cm.getPage(src.group(1), urlParams)
                if not sts:
                    return []
            elif "<form" in data:
                data = jw_hidden(data, baseUrl)
        if "function(p,a,c,k,e" in data:
            data = get_packed_data(data)
            if not data:
                return []
        host = urlparser.getDomain(baseUrl, False)
        url = re.search(r"""["']((?:https?:)?//[^'^"]+?\.(?:mp4|m3u8|mkv)(?:\?[^"^']+?)?)["']""", data)
        if not url:
            url = re.search(r"""file":"([^"]+)""", data)
        subTracks = []
        sub = re.findall(r"""{\s*file:\s*["']([^"']+)["'],\s*label:\s*["']([^"']+)["'],\s*kind:\s*["'](?:captions|subtitles)["']""", data)
        if not sub:
            sub = re.findall(r"""file_path":"([^"]+)","language":"([^"]+)""", data)
        if sub:
            for src, label in sub:
                src = src.replace(r"\/", "/")
                subTracks.append({"title": "", "url": "https:" + src if src.startswith("//") else src, "lang": label})
        if url:
            url = url.group(1)
            url = "https:" + url if url.startswith("//") else url
            url = urlparser.decorateUrl(url, {"User-Agent": HTTP_HEADER["User-Agent"], "Referer": host, "Origin": host[:-1], "external_sub_tracks": subTracks})
            if ".m3u8" in url:
                urltab.extend(getDirectM3U8Playlist(url))
            else:
                urltab.append({"name": "MP4", "url": url})
        return urltab

    def parserOKRU(self, baseUrl):  # Fix 061225
        printDBG("parserOKRU baseUrl[%s]" % baseUrl)
        host = urlparser.getDomain(baseUrl, False)
        HTTP_HEADER = self.cm.getDefaultHeader(browser="chrome")
        sts, data = self.cm.getPage(baseUrl, {"header": HTTP_HEADER})
        if not sts:
            return []
        urltab = []
        match = re.search(r'data-options="([^"]+)', data)
        if match:
            match = match.group(1).replace("&quot;", '"').replace("&amp;", "&")
            js = json_loads(match).get("flashvars", {}).get("metadata")
            js = json_loads(js)
            url = js.get("hlsManifestUrl") or js.get("ondemandHls") or js.get("hlsMasterPlaylistUrl")
            if url:
                url = urlparser.decorateUrl(url, {"User-Agent": HTTP_HEADER["User-Agent"], "Referer": host, "Origin": host[:-1]})
                urltab.extend(getDirectM3U8Playlist(url, sortWithMaxBitrate=99999999))
        return urltab
